[GH-ISSUE #7155] Error when updating an array field #10749

Open
opened 2026-04-13 07:04:52 -05:00 by GiteaMirror · 11 comments
Owner

Originally created by @aemonm on GitHub (Jan 6, 2026).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/7155

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

In recent versions (>=1.3.34), when I try and update an array field in my users model, I get the following error:

SERVER_ERROR:  [error: malformed array literal: "["other","media","research"]"] {
  length: 208,
  severity: 'ERROR',
  code: '22P02',
  detail: '"[" must introduce explicitly-specified array dimensions.',
  hint: undefined,
  position: undefined,
  internalPosition: undefined,
  internalQuery: undefined,
  where: "unnamed portal parameter $3 = '...'",
  schema: undefined,
  table: undefined,
  column: undefined,
  dataType: undefined,
  constraint: undefined,
  file: 'arrayfuncs.c',
  line: '273',
  routine: 'array_in'
}

This is my configuration:

 additionalFields: {
      organization: {
        type: 'string',
        input: true,
        required: false
      },
      organizationType: {
        type: 'string[]',
        input: true,
        required: false
      },
      role: {
        type: 'string',
        required: true,
        defaultValue: 'user',
        input: false // don't allow user to set role
      },
      firstName: {
        type: 'string',
        defaultValue: '', // currently this is not-nullable in the DB
        required: true,
        input: true
      },
      lastName: {
        type: 'string',
        defaultValue: '', // currently this is not-nullable in the DB
        required: true,
        input: true
      },
      location: {
        type: 'string',
        required: false,
        input: true
      },
      emailConsent: {
        type: 'boolean',
        required: false,
        defaultValue: false,
        input: true
      }
    }
  }

In versions 1.3.34 (possibly later). There is no error and the update succeeds.

Current vs. Expected behavior

I expect to be able to use array columns as in recent versions as I did in earlier versions.

What version of Better Auth are you using?

1.4.10

System info

{
  "system": {
    "platform": "darwin",
    "arch": "arm64",
    "version": "Darwin Kernel Version 25.1.0: Mon Oct 20 19:32:41 PDT 2025; root:xnu-12377.41.6~2/RELEASE_ARM64_T6000",
    "release": "25.1.0",
    "cpuCount": 10,
    "cpuModel": "Apple M1 Pro",
    "totalMemory": "16.00 GB",
    "freeMemory": "0.32 GB"
  },
  "node": {
    "version": "v24.2.0",
    "env": "development"
  },
  "packageManager": {
    "name": "npm",
    "version": "11.3.0"
  },
  "frameworks": [
    {
      "name": "next",
      "version": "^15.1.4"
    },
    {
      "name": "react",
      "version": "18.3.1"
    }
  ],
  "databases": [
    {
      "name": "pg",
      "version": "^8.16.3"
    },
    {
      "name": "postgres",
      "version": "^3.4.4"
    }
  ],
  "betterAuth": {
    "version": "^1.4.10",
    "config": null
  }
}

Which area(s) are affected? (Select all that apply)

Backend

Auth config (if applicable)


Additional context

No response

Originally created by @aemonm on GitHub (Jan 6, 2026). Original GitHub issue: https://github.com/better-auth/better-auth/issues/7155 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce In recent versions (>=1.3.34), when I try and update an array field in my users model, I get the following error: ``` SERVER_ERROR: [error: malformed array literal: "["other","media","research"]"] { length: 208, severity: 'ERROR', code: '22P02', detail: '"[" must introduce explicitly-specified array dimensions.', hint: undefined, position: undefined, internalPosition: undefined, internalQuery: undefined, where: "unnamed portal parameter $3 = '...'", schema: undefined, table: undefined, column: undefined, dataType: undefined, constraint: undefined, file: 'arrayfuncs.c', line: '273', routine: 'array_in' } ``` This is my configuration: ``` additionalFields: { organization: { type: 'string', input: true, required: false }, organizationType: { type: 'string[]', input: true, required: false }, role: { type: 'string', required: true, defaultValue: 'user', input: false // don't allow user to set role }, firstName: { type: 'string', defaultValue: '', // currently this is not-nullable in the DB required: true, input: true }, lastName: { type: 'string', defaultValue: '', // currently this is not-nullable in the DB required: true, input: true }, location: { type: 'string', required: false, input: true }, emailConsent: { type: 'boolean', required: false, defaultValue: false, input: true } } } ``` In versions 1.3.34 (possibly later). There is no error and the update succeeds. ### Current vs. Expected behavior I expect to be able to use array columns as in recent versions as I did in earlier versions. ### What version of Better Auth are you using? 1.4.10 ### System info ```bash { "system": { "platform": "darwin", "arch": "arm64", "version": "Darwin Kernel Version 25.1.0: Mon Oct 20 19:32:41 PDT 2025; root:xnu-12377.41.6~2/RELEASE_ARM64_T6000", "release": "25.1.0", "cpuCount": 10, "cpuModel": "Apple M1 Pro", "totalMemory": "16.00 GB", "freeMemory": "0.32 GB" }, "node": { "version": "v24.2.0", "env": "development" }, "packageManager": { "name": "npm", "version": "11.3.0" }, "frameworks": [ { "name": "next", "version": "^15.1.4" }, { "name": "react", "version": "18.3.1" } ], "databases": [ { "name": "pg", "version": "^8.16.3" }, { "name": "postgres", "version": "^3.4.4" } ], "betterAuth": { "version": "^1.4.10", "config": null } } ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript ``` ### Additional context _No response_
GiteaMirror added the databasebug labels 2026-04-13 07:04:53 -05:00
Author
Owner

@better-auth-agent[bot] commented on GitHub (Jan 6, 2026):

It looks like you're experiencing an error when trying to update an array field in your configuration with Better Auth version 1.4.10. The error message indicates that there might be an issue with the format of the array being submitted, particularly regarding how array dimensions are defined.

Based on the error details you've provided, it seems that the array is not being accepted in its current string representation. This issue could stem from the database interaction layer not properly interpreting the array format being sent from your application. In different versions, notably 1.3.34 and earlier, the error doesn’t occur, suggesting some backward compatibility might be affected in later releases.

To help troubleshoot this issue, consider the following steps:

  1. Ensure that the array you are trying to update is properly formatted according to the requirements of your database.
  2. Review the differences in array handling in the release notes between the versions you mentioned (1.3.34 and 1.4.10).
  3. Check if there's any ongoing discussion or a solution to a similar problem in the Better Auth community or GitHub issues.

If the problem persists, I recommend tagging the Better Auth team members, Beka and Max, with @bekacru and @ping__ respectively for further assistance, as they may provide more insights specific to this version.

Have you tried checking the array format being sent to the database to ensure it aligns with the required input?

If you need more help, tag @better-auth-agent in a comment so I can respond.

DiagramDiscordGitHub

Diagram Join Star

<!-- gh-comment-id:3716114858 --> @better-auth-agent[bot] commented on GitHub (Jan 6, 2026): It looks like you're experiencing an error when trying to update an array field in your configuration with Better Auth version 1.4.10. The error message indicates that there might be an issue with the format of the array being submitted, particularly regarding how array dimensions are defined. Based on the error details you've provided, it seems that the array is not being accepted in its current string representation. This issue could stem from the database interaction layer not properly interpreting the array format being sent from your application. In different versions, notably 1.3.34 and earlier, the error doesn’t occur, suggesting some backward compatibility might be affected in later releases. To help troubleshoot this issue, consider the following steps: 1. Ensure that the array you are trying to update is properly formatted according to the requirements of your database. 2. Review the differences in array handling in the release notes between the versions you mentioned (1.3.34 and 1.4.10). 3. Check if there's any ongoing discussion or a solution to a similar problem in the Better Auth community or GitHub issues. If the problem persists, I recommend tagging the Better Auth team members, Beka and Max, with @bekacru and @ping__ respectively for further assistance, as they may provide more insights specific to this version. Have you tried checking the array format being sent to the database to ensure it aligns with the required input? _If you need more help, tag @better-auth-agent in a comment so I can respond._ <!-- bot:webhook reply v1 --> [Diagram](https://repodiagrams.s3.eu-north-1.amazonaws.com/skyvern_ultra_detailed_interactive.html) • [Discord](https://discord.gg/fG2XXEuQX3) • [GitHub](https://github.com/Skyvern-AI/Skyvern) [![Diagram](https://img.shields.io/badge/Diagram-2b3137?style=flat-square)](https://repodiagrams.s3.eu-north-1.amazonaws.com/skyvern_ultra_detailed_interactive.html) [![Join](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&style=flat-square)](https://discord.gg/fG2XXEuQX3) [![Star](https://img.shields.io/badge/star-181717?logo=github&logoColor=white&style=flat-square)](https://github.com/Skyvern-AI/Skyvern)
Author
Owner

@dosubot[bot] commented on GitHub (Jan 6, 2026):

Hi @aemonm! I'm Dosu and I’m helping the better-auth team.

This error is caused by a change in Better Auth ≥1.4.x: array fields like organizationType: string[] are now stored as JSON strings (e.g., ["other","media","research"]) or as jsonb columns in PostgreSQL, instead of native Postgres arrays (text[]). If your database expects a native array but receives a JSON string, you get the malformed array literal error (source, source).

How to fix:

  1. Check your database schema: Is the affected column (organizationType) currently jsonb or text[]?

    • If it's jsonb, your ORM/schema should expect a JSON array, not a native array.
    • If it's text[], Better Auth may be sending JSON strings instead of native arrays, causing the error.
  2. If you need native arrays (e.g., for Drizzle):

    • Edit packages/better-auth/src/db/get-migration.ts and change the mapping for "string[]" under the postgres key from "jsonb" to "text[]" (reference):
      "string[]": {
      -    sqlite: "text",
      -    postgres: "jsonb",
      +    sqlite: "text",
      +    postgres: "text[]",
           mysql: "json",
           mssql: "varchar(8000)",
      },
      
    • Regenerate your migrations and migrate any existing data from jsonb to text[] using SQL (e.g., ALTER TABLE users ALTER COLUMN organizationType TYPE text[] USING organizationType::text[];).
  3. If you want to keep using jsonb:

    • Make sure your ORM/schema expects a JSON array for this field, not a native array.
  4. Check for validators or transform functions: If you have custom validators or transforms in your Better Auth config, they might affect serialization. Remove or adjust them if necessary (source).

Let me know your current schema and ORM setup if you need more specific migration or code snippets.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other

Chat with Dosu Open in Cursor Join Discord Share on X

<!-- gh-comment-id:3716149927 --> @dosubot[bot] commented on GitHub (Jan 6, 2026): <!-- Greeting --> Hi @aemonm! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> This error is caused by a change in Better Auth ≥1.4.x: array fields like `organizationType: string[]` are now stored as JSON strings (e.g., `["other","media","research"]`) or as `jsonb` columns in PostgreSQL, instead of native Postgres arrays (`text[]`). If your database expects a native array but receives a JSON string, you get the `malformed array literal` error ([source](https://github.com/better-auth/better-auth/issues/6779#issuecomment-3656307346), [source](https://github.com/better-auth/better-auth/blob/c31c92f3d24f3ccfb6776d4634e0681c6dee2db5/packages/better-auth/src/db/get-migration.ts#L281-L395)). **How to fix:** 1. **Check your database schema:** Is the affected column (`organizationType`) currently `jsonb` or `text[]`? - If it's `jsonb`, your ORM/schema should expect a JSON array, not a native array. - If it's `text[]`, Better Auth may be sending JSON strings instead of native arrays, causing the error. 2. **If you need native arrays (e.g., for Drizzle):** - Edit `packages/better-auth/src/db/get-migration.ts` and change the mapping for `"string[]"` under the `postgres` key from `"jsonb"` to `"text[]"` ([reference](https://github.com/better-auth/better-auth/issues/6779#issuecomment-3656307346)): ```diff "string[]": { - sqlite: "text", - postgres: "jsonb", + sqlite: "text", + postgres: "text[]", mysql: "json", mssql: "varchar(8000)", }, ``` - Regenerate your migrations and migrate any existing data from `jsonb` to `text[]` using SQL (e.g., `ALTER TABLE users ALTER COLUMN organizationType TYPE text[] USING organizationType::text[];`). 3. **If you want to keep using `jsonb`:** - Make sure your ORM/schema expects a JSON array for this field, not a native array. 4. **Check for validators or transform functions:** If you have custom validators or transforms in your Better Auth config, they might affect serialization. Remove or adjust them if necessary ([source](https://github.com/better-auth/better-auth/issues/6975#issuecomment-3689282844)). Let me know your current schema and ORM setup if you need more specific migration or code snippets. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/f7847a30-721b-4688-8151-bbf016babab0?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/f7847a30-721b-4688-8151-bbf016babab0?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/f7847a30-721b-4688-8151-bbf016babab0?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/f7847a30-721b-4688-8151-bbf016babab0?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/f7847a30-721b-4688-8151-bbf016babab0?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/f7847a30-721b-4688-8151-bbf016babab0?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/f7847a30-721b-4688-8151-bbf016babab0?feedback_type=other)</sup> [![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=This%20error%20is%20caused%20by%20a%20change%20in%20Better%20Auth%20%E2%89%A51.4.x%3A%20array%20fields%20like%20%60organizationType%3A%20string%5B%5D%60%20are%20now%20stored%20as%20JSON%20strings%20%28e.g.%2C%20%60%5B%22other%22%2C%22media%22%2C%22research%22%5D%60%29%20or%20as%20%60jsonb%60%20columns%20in%20PostgreSQL%2C%20instead%20of%20native%20Postgres%20arrays%20%28%60text%5B%5D%60%29.%20If%20your%20database%20expects%20a%20native%20array%20but%20receives%20a%20JSON%20string%2C%20you%20get%20the%20%60malformed%20array%20literal%60%20error%20%28%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/issues/6779%23issuecomment-3656307346%29%2C%20%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/blob/c31c92f3d24f3ccfb6776d4634e0681c6dee2db5/packages/better-auth/src/db/get-migration.ts%23L281-L395%29%29.%0A%0A%2A%2AHow%20to%20fix%3A%2A%2A%0A%0A1.%20%2A%2ACheck%20your%20database%20schema%3A%2A%2A%20Is%20the%20affected%20column%20%28%60organizationType%60%29%20currently%20%60jsonb%60%20or%20%60text%5B%5D%60%3F%20%20%0A%20%20%20-%20If%20it%27s%20%60jsonb%60%2C%20your%20ORM/schema%20should%20expect%20a%20JSON%20array%2C%20not%20a%20native%20array.%0A%20%20%20-%20If%20it%27s%20%60text%5B%5D%60%2C%20Better%20Auth%20may%20be%20sending%20JSON%20strings%20instead%20of%20native%20arrays%2C%20causing%20the%20error.%0A%0A2.%20%2A%2AIf%20you%20need%20native%20arrays%20%28e.g.%2C%20for%20Drizzle%29%3A%2A%2A%0A%20%20%20-%20Edit%20%60packages/better-auth/src/db/get-migration.ts%60%20and%20change%20the%20mapping%20for%20%60%22string%5B%5D%22%60%20under%20the%20%60postgres%60%20key%20from%20%60%22jsonb%22%60%20to%20%60%22text%5B%5D%22%60%20%28%5Breference%5D%28https%3A//github.com/better-auth/better-auth/issues/6779%23issuecomment-3656307346%29%29%3A%0A%20%20%20%20%20%60%60%60diff%0A%20%20%20%20%20%22string%5B%5D%22%3A%20%7B%0A%20%20%20%20%20-%20%20%20%20sqlite%3A%20%22text%22%2C%0A%20%20%20%20%20-%20%20%20%20postgres%3A%20%22jsonb%22%2C%0A%20%20%20%20%20%2B%20%20%20%20sqlite%3A%20%22text%22%2C%0A%20%20%20%20%20%2B%20%20%20%20postgres%3A%20%22text%5B%5D%22%2C%0A%20%20%20%20%20%20%20%20%20%20mysql%3A%20%22json%22%2C%0A%20%20%20%20%20%20%20%20%20%20mssql%3A%20%22varchar%288000%29%22%2C%0A%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%60%60%60%0A%20%20%20-%20Regenerate%20your%20migrations%20and%20migrate%20any%20existing%20data%20from%20%60jsonb%60%20to%20%60text%5B%5D%60%20using%20SQL%20%28e.g.%2C%20%60ALTER%20TABLE%20users%20ALTER%20COLUMN%20organizationType%20TYPE%20text%5B%5D%20USING%20organizationType%3A%3Atext%5B%5D%3B%60%29.%0A%0A3.%20%2A%2AIf%20you%20want%20to%20keep%20using%20%60jsonb%60%3A%2A%2A%0A%20%20%20-%20Make%20sure%20your%20ORM/schema%20expects%20a%20JSON%20array%20for%20this%20field%2C%20not%20a%20native%20array.%0A%0A4.%20%2A%2ACheck%20for%20validators%20or%20transform%20functions%3A%2A%2A%20If%20you%20have%20custom%20validators%20or%20transforms%20in%20your%20Better%20Auth%20config%2C%20they%20might%20affect%20serialization.%20Remove%20or%20adjust%20them%20if%20necessary%20%28%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/issues/6975%23issuecomment-3689282844%29%29.%0A%0ALet%20me%20know%20your%20current%20schema%20and%20ORM%20setup%20if%20you%20need%20more%20specific%20migration%20or%20code%20snippets.)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/7155)
Author
Owner

@aemonm commented on GitHub (Jan 6, 2026):

@dosu the database column for organizationType is text[] . Is better-auth now expecting string[] to have a jsonb array type in the database?

<!-- gh-comment-id:3716177576 --> @aemonm commented on GitHub (Jan 6, 2026): @dosu the database column for organizationType is `text[]` . Is better-auth now expecting `string[]` to have a jsonb array type in the database?
Author
Owner

@dosubot[bot] commented on GitHub (Jan 6, 2026):

Yes—starting in Better Auth v1.4.x, fields declared as type string[] are mapped to jsonb columns in PostgreSQL by default, not native text[] arrays. This means Better Auth expects the database column for organizationType to be jsonb unless you manually change the migration logic. If your column is still text[], you'll get errors like the malformed array literal, because Better Auth is sending JSON arrays (e.g., ["a","b"]) instead of Postgres array literals (e.g., {a,b}) source.

If you want to keep using native arrays, you need to edit the migration logic in get-migration.ts to map string[] to text[] for Postgres, then update your schema and migrate any existing data source. There’s currently no config option to force native array storage; it requires a manual change.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other

Chat with Dosu Open in Cursor Join Discord Share on X

<!-- gh-comment-id:3716186317 --> @dosubot[bot] commented on GitHub (Jan 6, 2026): <!-- Answer --> Yes—starting in Better Auth v1.4.x, fields declared as type `string[]` are mapped to `jsonb` columns in PostgreSQL by default, not native `text[]` arrays. This means Better Auth expects the database column for `organizationType` to be `jsonb` unless you manually change the migration logic. If your column is still `text[]`, you'll get errors like the malformed array literal, because Better Auth is sending JSON arrays (e.g., `["a","b"]`) instead of Postgres array literals (e.g., `{a,b}`) [source](https://github.com/better-auth/better-auth/issues/6779). If you want to keep using native arrays, you need to edit the migration logic in `get-migration.ts` to map `string[]` to `text[]` for Postgres, then update your schema and migrate any existing data [source](https://github.com/better-auth/better-auth/blob/c31c92f3d24f3ccfb6776d4634e0681c6dee2db5/packages/better-auth/src/db/get-migration.ts#L216-L545). There’s currently no config option to force native array storage; it requires a manual change. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/883c6c8f-fa24-4ffc-b5a7-73de79281bcb?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/883c6c8f-fa24-4ffc-b5a7-73de79281bcb?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/883c6c8f-fa24-4ffc-b5a7-73de79281bcb?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/883c6c8f-fa24-4ffc-b5a7-73de79281bcb?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/883c6c8f-fa24-4ffc-b5a7-73de79281bcb?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/883c6c8f-fa24-4ffc-b5a7-73de79281bcb?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/883c6c8f-fa24-4ffc-b5a7-73de79281bcb?feedback_type=other)</sup> [![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=Yes%E2%80%94starting%20in%20Better%20Auth%20v1.4.x%2C%20fields%20declared%20as%20type%20%60string%5B%5D%60%20are%20mapped%20to%20%60jsonb%60%20columns%20in%20PostgreSQL%20by%20default%2C%20not%20native%20%60text%5B%5D%60%20arrays.%20This%20means%20Better%20Auth%20expects%20the%20database%20column%20for%20%60organizationType%60%20to%20be%20%60jsonb%60%20unless%20you%20manually%20change%20the%20migration%20logic.%20If%20your%20column%20is%20still%20%60text%5B%5D%60%2C%20you%27ll%20get%20errors%20like%20the%20malformed%20array%20literal%2C%20because%20Better%20Auth%20is%20sending%20JSON%20arrays%20%28e.g.%2C%20%60%5B%22a%22%2C%22b%22%5D%60%29%20instead%20of%20Postgres%20array%20literals%20%28e.g.%2C%20%60%7Ba%2Cb%7D%60%29%20%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/issues/6779%29.%0A%0AIf%20you%20want%20to%20keep%20using%20native%20arrays%2C%20you%20need%20to%20edit%20the%20migration%20logic%20in%20%60get-migration.ts%60%20to%20map%20%60string%5B%5D%60%20to%20%60text%5B%5D%60%20for%20Postgres%2C%20then%20update%20your%20schema%20and%20migrate%20any%20existing%20data%20%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/blob/c31c92f3d24f3ccfb6776d4634e0681c6dee2db5/packages/better-auth/src/db/get-migration.ts%23L216-L545%29.%20There%E2%80%99s%20currently%20no%20config%20option%20to%20force%20native%20array%20storage%3B%20it%20requires%20a%20manual%20change.)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/7155)
Author
Owner

@bytaesu commented on GitHub (Jan 7, 2026):

@ping-maxwell could you handle this? seems related to #6601

<!-- gh-comment-id:3717978204 --> @bytaesu commented on GitHub (Jan 7, 2026): @ping-maxwell could you handle this? seems related to #6601
Author
Owner

@ping-maxwell commented on GitHub (Jan 7, 2026):

Hello @aemonm what database adpater are you using?

<!-- gh-comment-id:3718077066 --> @ping-maxwell commented on GitHub (Jan 7, 2026): Hello @aemonm what database adpater are you using?
Author
Owner

@aemonm commented on GitHub (Jan 7, 2026):

@ping-maxwell

Postgres.

Here's my complete config:

import axios from 'axios';
import { betterAuth } from 'better-auth';
import { nextCookies } from 'better-auth/next-js';
import { toNodeHandler } from 'better-auth/node';
import { admin, magicLink } from 'better-auth/plugins';
import type { NextApiRequest } from 'next';
import nodemailer from 'nodemailer';

import { pgPool, pgSql } from '@/libs/db/pg';

const transporter = nodemailer.createTransport({
  // @ts-ignore
  host: process.env.EMAIL_HOST,
  port: process.env.EMAIL_PORT,
  secure: false,
  auth: {
    user: process.env.EMAIL_USER,
    pass: process.env.EMAIL_PASSWORD
  }
});

export const auth = betterAuth({
  advanced: {
    ipAddress: {
      disableIpTracking: false
    },
    database: {
      generateId: false
    }
  },
  account: {
    modelName: 'accounts'
  },
  session: {
    modelName: 'sessions',
    session: {
      cookieCache: {
        enabled: true,
        maxAge: 5 * 60 // Cache duration in seconds
      }
    }
  },
  verification: {
    modelName: 'verifications'
  },
  user: {
    modelName: 'users',
    deleteUser: {
      enabled: true,
      beforeDelete: async (user, request) => {
        await pgSql`DELETE FROM hitl_request WHERE "user" = ${user.id}`;
        if (process.env.NODE_ENV === 'development') {
          await pgSql`DELETE FROM hitl_slick WHERE "user" = ${user.id}`;
          await pgSql`DELETE FROM slick_to_source WHERE hitl_user = ${user.id}`;
        }
      },
      sendDeleteAccountVerification: async (
        {
          user, 
          url, 
          token 
        },
        request // The original request object (optional)
      ) => {
        // Your email sending logic here
        // Example: sendEmail(data.user.email, "Verify Deletion", data.url);
        const result = await transporter.sendMail({
          from: '"MyOrg" <no-reply@org.org>',
          to: user.email,
          subject: 'Delete Your Account',
          text: 'Delete Your Account', // plain‑text body
          html: `
            <div>
              <div>
                <img
                  width="200px"
                  src="logo.png"
                  />
              </div>
              <p>
                We're sorry to see you go! Please <a href="${url}">click this link to complete your account deletion</a>.
                If you would like to offer feedback to help us improve Cerulean, please <a href="">let us know</a>.
              </p>
              <p>
                If you did not make this request, please
                <a href="">contact support</a>.
              </p>
            </div>`
        });
      }
    },
    additionalFields: {
      organization: {
        type: 'string',
        input: true,
        required: false
      },
      organizationType: {
        type: 'string[]',
        input: true,
        required: false
      },
      role: {
        type: 'string',
        required: true,
        defaultValue: 'user',
        input: false // don't allow user to set role
      },
      firstName: {
        type: 'string',
        defaultValue: '', // currently this is not-nullable in the DB
        required: true,
        input: true
      },
      lastName: {
        type: 'string',
        defaultValue: '', // currently this is not-nullable in the DB
        required: true,
        input: true
      },
      location: {
        type: 'string',
        required: false,
        input: true
      },
      emailConsent: {
        type: 'boolean',
        required: false,
        defaultValue: false,
        input: true
      }
    }
  },
  database: pgPool,
  baseURL: process.env.BASE_URL,
  databaseHooks: {
    user: {
      create: {
        before: async (user, context) => {
          return {
            data: {
              ...user,
              // @ts-ignore
              firstName: user.firstName || '',
              // @ts-ignore
              lastName: user.lastName || '',
              role: user.email.endsWith('@org.org') ? 'admin' : 'user'
            }
          };
        }
      }
    }
  },
  emailAndPassword: {
    enabled: false
  },
  socialProviders: {
    google: {
      clientId: process.env.GOOGLE_AUTH_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_AUTH_CLIENT_SECRET!
    },
    facebook: {
      clientId: process.env.FACEBOOK_CLIENT_ID!,
      clientSecret: process.env.FACEBOOK_CLIENT_SECRET!
    },
    microsoft: {
      clientId: process.env.MICROSOFT_CLIENT_ID!,
      clientSecret: process.env.MICROSOFT_CLIENT_SECRET!
    },
    linkedin: {
      clientId: process.env.LINKEDIN_CLIENT_ID!,
      clientSecret: process.env.LINKEDIN_CLIENT_SECRET!
    }
  },

  plugins: [
    nextCookies(),
    admin(), 
    magicLink({
      expiresIn: 86400, // 24 hours
      async sendMagicLink({ email, url }) {
        try {
          const result = await transporter.sendMail({
            from: '"My Org" <no-reply@myorg.org>',
            to: email,
            subject: 'Sign In to My App',
            text: 'Hello world?', // plain‑text body
            html: `
              <div>
                <div>
                  <img
                    width="200px"
                    src="logo.png"
                    />
                </div>
                <p>
                  Hello! You're receiving this email because we received a request to
                  sign in to your account. <a href="${url}">Click here to sign in</a>.
                </p>
                <p>
                  If you did not make this request, please
                  <a href="mailto:support@myorg.org">let us know</a>.
                </p>
              </div>`
          });
        } catch (e) {
          console.error(e);
        }
      }
    })
  ]
});

export type Session = typeof auth.$Infer.Session;

export const getAPISession = (req: NextApiRequest) => {
  return axios<Session | null>(`${process.env.BASE_URL}/api/auth/get-session`, {
    baseURL: req.headers.origin,
    headers: {
      cookie: req.headers['cookie'] || '' // Forward the cookies from the request
    }
  });
};

export const config = { api: { bodyParser: false } };

export default toNodeHandler(auth.handler);
<!-- gh-comment-id:3719416361 --> @aemonm commented on GitHub (Jan 7, 2026): @ping-maxwell Postgres. Here's my complete config: ```typescript import axios from 'axios'; import { betterAuth } from 'better-auth'; import { nextCookies } from 'better-auth/next-js'; import { toNodeHandler } from 'better-auth/node'; import { admin, magicLink } from 'better-auth/plugins'; import type { NextApiRequest } from 'next'; import nodemailer from 'nodemailer'; import { pgPool, pgSql } from '@/libs/db/pg'; const transporter = nodemailer.createTransport({ // @ts-ignore host: process.env.EMAIL_HOST, port: process.env.EMAIL_PORT, secure: false, auth: { user: process.env.EMAIL_USER, pass: process.env.EMAIL_PASSWORD } }); export const auth = betterAuth({ advanced: { ipAddress: { disableIpTracking: false }, database: { generateId: false } }, account: { modelName: 'accounts' }, session: { modelName: 'sessions', session: { cookieCache: { enabled: true, maxAge: 5 * 60 // Cache duration in seconds } } }, verification: { modelName: 'verifications' }, user: { modelName: 'users', deleteUser: { enabled: true, beforeDelete: async (user, request) => { await pgSql`DELETE FROM hitl_request WHERE "user" = ${user.id}`; if (process.env.NODE_ENV === 'development') { await pgSql`DELETE FROM hitl_slick WHERE "user" = ${user.id}`; await pgSql`DELETE FROM slick_to_source WHERE hitl_user = ${user.id}`; } }, sendDeleteAccountVerification: async ( { user, url, token }, request // The original request object (optional) ) => { // Your email sending logic here // Example: sendEmail(data.user.email, "Verify Deletion", data.url); const result = await transporter.sendMail({ from: '"MyOrg" <no-reply@org.org>', to: user.email, subject: 'Delete Your Account', text: 'Delete Your Account', // plain‑text body html: ` <div> <div> <img width="200px" src="logo.png" /> </div> <p> We're sorry to see you go! Please <a href="${url}">click this link to complete your account deletion</a>. If you would like to offer feedback to help us improve Cerulean, please <a href="">let us know</a>. </p> <p> If you did not make this request, please <a href="">contact support</a>. </p> </div>` }); } }, additionalFields: { organization: { type: 'string', input: true, required: false }, organizationType: { type: 'string[]', input: true, required: false }, role: { type: 'string', required: true, defaultValue: 'user', input: false // don't allow user to set role }, firstName: { type: 'string', defaultValue: '', // currently this is not-nullable in the DB required: true, input: true }, lastName: { type: 'string', defaultValue: '', // currently this is not-nullable in the DB required: true, input: true }, location: { type: 'string', required: false, input: true }, emailConsent: { type: 'boolean', required: false, defaultValue: false, input: true } } }, database: pgPool, baseURL: process.env.BASE_URL, databaseHooks: { user: { create: { before: async (user, context) => { return { data: { ...user, // @ts-ignore firstName: user.firstName || '', // @ts-ignore lastName: user.lastName || '', role: user.email.endsWith('@org.org') ? 'admin' : 'user' } }; } } } }, emailAndPassword: { enabled: false }, socialProviders: { google: { clientId: process.env.GOOGLE_AUTH_CLIENT_ID!, clientSecret: process.env.GOOGLE_AUTH_CLIENT_SECRET! }, facebook: { clientId: process.env.FACEBOOK_CLIENT_ID!, clientSecret: process.env.FACEBOOK_CLIENT_SECRET! }, microsoft: { clientId: process.env.MICROSOFT_CLIENT_ID!, clientSecret: process.env.MICROSOFT_CLIENT_SECRET! }, linkedin: { clientId: process.env.LINKEDIN_CLIENT_ID!, clientSecret: process.env.LINKEDIN_CLIENT_SECRET! } }, plugins: [ nextCookies(), admin(), magicLink({ expiresIn: 86400, // 24 hours async sendMagicLink({ email, url }) { try { const result = await transporter.sendMail({ from: '"My Org" <no-reply@myorg.org>', to: email, subject: 'Sign In to My App', text: 'Hello world?', // plain‑text body html: ` <div> <div> <img width="200px" src="logo.png" /> </div> <p> Hello! You're receiving this email because we received a request to sign in to your account. <a href="${url}">Click here to sign in</a>. </p> <p> If you did not make this request, please <a href="mailto:support@myorg.org">let us know</a>. </p> </div>` }); } catch (e) { console.error(e); } } }) ] }); export type Session = typeof auth.$Infer.Session; export const getAPISession = (req: NextApiRequest) => { return axios<Session | null>(`${process.env.BASE_URL}/api/auth/get-session`, { baseURL: req.headers.origin, headers: { cookie: req.headers['cookie'] || '' // Forward the cookies from the request } }); }; export const config = { api: { bodyParser: false } }; export default toNodeHandler(auth.handler); ```
Author
Owner

@ping-maxwell commented on GitHub (Jan 8, 2026):

@aemonm With the currently broken field, what field type is it in your DB?

I'll try to see if I can reproduce it on my end.

<!-- gh-comment-id:3722797046 --> @ping-maxwell commented on GitHub (Jan 8, 2026): @aemonm With the currently broken field, what field type is it in your DB? I'll try to see if I can reproduce it on my end.
Author
Owner

@aemonm commented on GitHub (Jan 9, 2026):

@ping-maxwell it's text[]

<!-- gh-comment-id:3726557405 --> @aemonm commented on GitHub (Jan 9, 2026): @ping-maxwell it's `text[]`
Author
Owner

@aemonm commented on GitHub (Jan 12, 2026):

@ping-maxwell any progress on reproducing this?

<!-- gh-comment-id:3740267920 --> @aemonm commented on GitHub (Jan 12, 2026): @ping-maxwell any progress on reproducing this?
Author
Owner

@aemonm commented on GitHub (Jan 22, 2026):

@ping-maxwell can you let me know if a fix is planned for this?

<!-- gh-comment-id:3784765633 --> @aemonm commented on GitHub (Jan 22, 2026): @ping-maxwell can you let me know if a fix is planned for this?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#10749