[GH-ISSUE #6975] string[] type field in user.additionalFields is incorrectly cast as string during email signup #19320

Closed
opened 2026-04-15 18:14:51 -05:00 by GiteaMirror · 6 comments
Owner

Originally created by @firatciftci on GitHub (Dec 24, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/6975

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. In auth.ts, set user.additionalFields to have a new field that has a string[] type
  2. Enable emailAndPassword signup mode.
  3. Call authClient.signUp.email() and set the string[] field to be an array of strings.
  4. Go to the database and observer that the field is a string instead.

Current vs. Expected behavior

The string[] additional field should be an array of strings. It is a string instead.

What version of Better Auth are you using?

1.4.9

System info

{
  "system": {
    "platform": "darwin",
    "arch": "arm64",
    "version": "Darwin Kernel Version 25.1.0: Mon Oct 20 19:34:05 PDT 2025; root:xnu-12377.41.6~2/RELEASE_ARM64_T6041",
    "release": "25.1.0",
    "cpuCount": 14,
    "cpuModel": "Apple M4 Pro",
    "totalMemory": "24.00 GB",
    "freeMemory": "0.18 GB"
  },
  "node": {
    "version": "v24.12.0",
    "env": "development"
  },
  "packageManager": {
    "name": "pnpm",
    "version": "10.26.1"
  },
  "frameworks": [
    {
      "name": "next",
      "version": "^16.1.0"
    },
    {
      "name": "react",
      "version": "^19.2.3"
    }
  ],
  "databases": [
    {
      "name": "mongodb",
      "version": "^6.21.0"
    }
  ],
  "betterAuth": {
    "version": "^1.4.9",
    "config": {
      "plugins": [
        {
          "name": "username",
          "config": {
            "id": "username",
            "endpoints": {},
            "schema": {
              "user": {
                "fields": {
                  "username": {
                    "type": "string",
                    "required": false,
                    "sortable": true,
                    "unique": true,
                    "returned": true,
                    "transform": {}
                  },
                  "displayUsername": {
                    "type": "string",
                    "required": false,
                    "transform": {}
                  }
                }
              }
            },
            "hooks": {
              "before": [{}, {}]
            },
            "$ERROR_CODES": {
              "INVALID_USERNAME_OR_PASSWORD": "[REDACTED]",
              "EMAIL_NOT_VERIFIED": "Email not verified",
              "UNEXPECTED_ERROR": "Unexpected error",
              "USERNAME_IS_ALREADY_TAKEN": "Username is already taken. Please try another.",
              "USERNAME_TOO_SHORT": "Username is too short",
              "USERNAME_TOO_LONG": "Username is too long",
              "INVALID_USERNAME": "Username is invalid",
              "INVALID_DISPLAY_USERNAME": "Display username is invalid"
            }
          }
        }
      ],
      "secret": "[REDACTED]",
      "emailAndPassword": {
        "enabled": true
      },
      "user": {
        "additionalFields": {
          "roles": {
            "type": "string[]",
            "required": true
          }
        }
      }
    }
  }
}

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

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth";
import { mongodbAdapter } from "better-auth/adapters/mongodb";
import { username } from 'better-auth/plugins';
import clientPromise from "./mongodb";

const client = await clientPromise;
const db = client.db("default");

export const auth = betterAuth({
  database: mongodbAdapter(db, { client, usePlural: true }),
  plugins: [username()],
  secret: process.env.BETTER_AUTH_SECRET,
  trustedOrigins: [process.env.PUBLIC_URL],
  emailAndPassword: {
    enabled: true,
  },
  user: {
    additionalFields: {
      roles: { type: "string[]", required: true },
    },
  },
});

Additional context

I am using MongoDB and connecting to Better Auth using the MongoDB plugin. My additional field is named roles, and here is how I call the sign up function in my code:

...
const data = req.body;
const uniqueUsername = await getUniqueUsername();

const { error } = await authClient.signUp.email({
  email: data.email.trim().toLowerCase(),
  name: data.username.trim(),
  username: uniqueUsername,
  password: data.password,
  roles: ["CONTRIBUTOR"],
 });

On my MongoDB database, the roles property for a newly created user shows up as a string that is exactly as follows: "["CONTRIBUTOR"]"; as you can see, this is a string type and not a string[] type, as if a JSON.stringify() call has been applied on my ["CONTRIBUTOR"] array of string variable.

I am not sure exactly when this regression started happening, but it is a very recent development.

Originally created by @firatciftci on GitHub (Dec 24, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/6975 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. In `auth.ts`, set `user.additionalFields` to have a new field that has a `string[]` type 2. Enable `emailAndPassword` signup mode. 3. Call `authClient.signUp.email()` and set the `string[]` field to be an array of strings. 4. Go to the database and observer that the field is a `string` instead. ### Current vs. Expected behavior The `string[]` additional field should be an array of strings. It is a string instead. ### What version of Better Auth are you using? 1.4.9 ### System info ```bash { "system": { "platform": "darwin", "arch": "arm64", "version": "Darwin Kernel Version 25.1.0: Mon Oct 20 19:34:05 PDT 2025; root:xnu-12377.41.6~2/RELEASE_ARM64_T6041", "release": "25.1.0", "cpuCount": 14, "cpuModel": "Apple M4 Pro", "totalMemory": "24.00 GB", "freeMemory": "0.18 GB" }, "node": { "version": "v24.12.0", "env": "development" }, "packageManager": { "name": "pnpm", "version": "10.26.1" }, "frameworks": [ { "name": "next", "version": "^16.1.0" }, { "name": "react", "version": "^19.2.3" } ], "databases": [ { "name": "mongodb", "version": "^6.21.0" } ], "betterAuth": { "version": "^1.4.9", "config": { "plugins": [ { "name": "username", "config": { "id": "username", "endpoints": {}, "schema": { "user": { "fields": { "username": { "type": "string", "required": false, "sortable": true, "unique": true, "returned": true, "transform": {} }, "displayUsername": { "type": "string", "required": false, "transform": {} } } } }, "hooks": { "before": [{}, {}] }, "$ERROR_CODES": { "INVALID_USERNAME_OR_PASSWORD": "[REDACTED]", "EMAIL_NOT_VERIFIED": "Email not verified", "UNEXPECTED_ERROR": "Unexpected error", "USERNAME_IS_ALREADY_TAKEN": "Username is already taken. Please try another.", "USERNAME_TOO_SHORT": "Username is too short", "USERNAME_TOO_LONG": "Username is too long", "INVALID_USERNAME": "Username is invalid", "INVALID_DISPLAY_USERNAME": "Display username is invalid" } } } ], "secret": "[REDACTED]", "emailAndPassword": { "enabled": true }, "user": { "additionalFields": { "roles": { "type": "string[]", "required": true } } } } } } ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth"; import { mongodbAdapter } from "better-auth/adapters/mongodb"; import { username } from 'better-auth/plugins'; import clientPromise from "./mongodb"; const client = await clientPromise; const db = client.db("default"); export const auth = betterAuth({ database: mongodbAdapter(db, { client, usePlural: true }), plugins: [username()], secret: process.env.BETTER_AUTH_SECRET, trustedOrigins: [process.env.PUBLIC_URL], emailAndPassword: { enabled: true, }, user: { additionalFields: { roles: { type: "string[]", required: true }, }, }, }); ``` ### Additional context I am using MongoDB and connecting to Better Auth using the MongoDB plugin. My additional field is named `roles`, and here is how I call the sign up function in my code: ```ts ... const data = req.body; const uniqueUsername = await getUniqueUsername(); const { error } = await authClient.signUp.email({ email: data.email.trim().toLowerCase(), name: data.username.trim(), username: uniqueUsername, password: data.password, roles: ["CONTRIBUTOR"], }); ``` On my MongoDB database, the roles property for a newly created user shows up as a string that is exactly as follows: `"["CONTRIBUTOR"]"`; as you can see, this is a `string` type and not a `string[]` type, as if a `JSON.stringify()` call has been applied on my `["CONTRIBUTOR"]` array of string variable. I am not sure exactly when this regression started happening, but it is a very recent development.
GiteaMirror added the lockedbug labels 2026-04-15 18:14:51 -05:00
Author
Owner

@better-auth-agent[bot] commented on GitHub (Dec 24, 2025):

It appears you're encountering an issue where the string[] type field in user.additionalFields is being incorrectly cast as a string during the email signup process. This aligns with other reported issues regarding the type inference for string arrays, particularly after recent updates to Better Auth.

The root cause seems to stem from incorrect type inference logic within the schema definition, which has resulted in the field being stored as a JSON string rather than an actual array. There is a known issue with array field types not being correctly interpreted, which could be the result of changes made in version updates [2][3].

To resolve this, please ensure that your configuration correctly specifies type: "string[]" for any additional fields that are intended to be arrays. If the problem persists, you may consider checking for any recent changes that might have impacted this behavior, or tagging the Better Auth team members, @bekacru and @ping__, for more specialized assistance.

As a next step, have you checked whether the latest updates resolved this issue, or are you continuing to face it? Let me know how else I can help!

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

DiagramDiscordGitHub

Diagram Join Star

<!-- gh-comment-id:3689268614 --> @better-auth-agent[bot] commented on GitHub (Dec 24, 2025): It appears you're encountering an issue where the `string[]` type field in `user.additionalFields` is being incorrectly cast as a `string` during the email signup process. This aligns with other reported issues regarding the type inference for string arrays, particularly after recent updates to Better Auth. The root cause seems to stem from incorrect type inference logic within the schema definition, which has resulted in the field being stored as a JSON string rather than an actual array. There is a known issue with array field types not being correctly interpreted, which could be the result of changes made in version updates [[2]](https://github.com/better-auth/better-auth/pull/5795)[[3]](https://github.com/better-auth/better-auth/issues/6779). To resolve this, please ensure that your configuration correctly specifies `type: "string[]"` for any additional fields that are intended to be arrays. If the problem persists, you may consider checking for any recent changes that might have impacted this behavior, or tagging the Better Auth team members, @bekacru and @ping__, for more specialized assistance. As a next step, have you checked whether the latest updates resolved this issue, or are you continuing to face it? Let me know how else I can help! _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

@firatciftci commented on GitHub (Dec 24, 2025):

@better-auth-agent My configuration correctly specifies type: "string[]". I am on the most recent version of Better Auth. This is a quite crucial regression that messes up my sign up flow, as a lot in my code depends on this additional field being an array of string. Please escalate this accordingly.

<!-- gh-comment-id:3689272837 --> @firatciftci commented on GitHub (Dec 24, 2025): @better-auth-agent My configuration correctly specifies `type: "string[]"`. I am on the most recent version of Better Auth. This is a quite crucial regression that messes up my sign up flow, as a lot in my code depends on this additional field being an array of string. Please escalate this accordingly.
Author
Owner

@better-auth-agent[bot] commented on GitHub (Dec 24, 2025):

It looks like you're experiencing an issue where the string[] type for the user.additionalFields (specifically roles) is being treated as a string in your MongoDB database. This can happen due to configuration or type inference issues.

There have been recent reports of similar issues, where user.additionalFields types were being improperly managed, especially after certain updates to Better Auth. One user reported that after a recent 1.4.x update, the string[] type was broken with Drizzle ORM and PostgreSQL, which could suggest a broader problem with type handling in the framework [4].

Since you're on version 1.4.7, it may be worth checking if this bug has been identified and addressed in subsequent releases or if workarounds have been suggested. Additionally, consider the following steps:

  1. Confirm Configuration: Double-check that your configuration for additionalFields is correctly defined in the context of your database adapter.
  2. Review Release Notes: Look at the release notes for any known bugs or fixes related to user.additionalFields.
  3. Testing: Try creating a new test user with roles set to another value or type and see if the problem persists. This can help determine if it’s a data format issue or a general bug.

Lastly, if you continue to have problems, I recommend tagging @bekacru or @ping__ in your queries, as they could provide more specific assistance regarding this matter.

What other aspects would you like to explore or clarify regarding Better Auth?

DiagramDiscordGitHub

Diagram Join Star

<!-- gh-comment-id:3689273295 --> @better-auth-agent[bot] commented on GitHub (Dec 24, 2025): It looks like you're experiencing an issue where the `string[]` type for the `user.additionalFields` (specifically `roles`) is being treated as a `string` in your MongoDB database. This can happen due to configuration or type inference issues. There have been recent reports of similar issues, where `user.additionalFields` types were being improperly managed, especially after certain updates to Better Auth. One user reported that after a recent 1.4.x update, the `string[]` type was broken with Drizzle ORM and PostgreSQL, which could suggest a broader problem with type handling in the framework [[4]](https://github.com/better-auth/better-auth/issues/6779). Since you're on version 1.4.7, it may be worth checking if this bug has been identified and addressed in subsequent releases or if workarounds have been suggested. Additionally, consider the following steps: 1. **Confirm Configuration**: Double-check that your configuration for `additionalFields` is correctly defined in the context of your database adapter. 2. **Review Release Notes**: Look at the release notes for any known bugs or fixes related to `user.additionalFields`. 3. **Testing**: Try creating a new test user with `roles` set to another value or type and see if the problem persists. This can help determine if it’s a data format issue or a general bug. Lastly, if you continue to have problems, I recommend tagging @bekacru or @ping__ in your queries, as they could provide more specific assistance regarding this matter. What other aspects would you like to explore or clarify regarding Better Auth? <!-- 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

@firatciftci commented on GitHub (Dec 24, 2025):

@Bekacru & @ping__ This is a major regression for additional fields. Please let me know if I should provide more details!

<!-- gh-comment-id:3689274596 --> @firatciftci commented on GitHub (Dec 24, 2025): @Bekacru & @ping__ This is a major regression for additional fields. Please let me know if I should provide more details!
Author
Owner

@dosubot[bot] commented on GitHub (Dec 24, 2025):

This is a known regression in Better Auth v1.4.x: fields defined as string[] in user.additionalFields are now stored as JSON strings (e.g., "[\"CONTRIBUTOR\"]") instead of native arrays in the database. This change affects multiple adapters, including MongoDB, and is due to upstream changes in validation and serialization logic—not the MongoDB adapter itself, which expects arrays and does not stringify them. The conversion to string happens earlier in the pipeline, likely when a validator is present or due to how additional fields are processed after v1.4.0 [source].

There is currently no config option to force native array storage for string[] fields. Workarounds for other databases involve editing migration logic, but for MongoDB, the only known workaround is to temporarily remove any validators on the affected field (if present), which may allow arrays to be stored natively again [source]. If you must use validators, you may need to manually parse the string back into an array when reading from the database.

This is a recent and widely reported issue, and the maintainers are aware. If you need to track progress or see more technical details, check the linked issues and discussions.

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:3689282844 --> @dosubot[bot] commented on GitHub (Dec 24, 2025): <!-- Answer --> This is a known regression in Better Auth v1.4.x: fields defined as `string[]` in `user.additionalFields` are now stored as JSON strings (e.g., `"[\"CONTRIBUTOR\"]"`) instead of native arrays in the database. This change affects multiple adapters, including MongoDB, and is due to upstream changes in validation and serialization logic—not the MongoDB adapter itself, which expects arrays and does not stringify them. The conversion to string happens earlier in the pipeline, likely when a validator is present or due to how additional fields are processed after v1.4.0 [[source](https://github.com/better-auth/better-auth/issues/6779#issuecomment-3656323266)]. There is currently no config option to force native array storage for `string[]` fields. Workarounds for other databases involve editing migration logic, but for MongoDB, the only known workaround is to temporarily remove any validators on the affected field (if present), which may allow arrays to be stored natively again [[source](https://github.com/better-auth/better-auth/issues/6482#issuecomment-3633671216)]. If you must use validators, you may need to manually parse the string back into an array when reading from the database. This is a recent and widely reported issue, and the maintainers are aware. If you need to track progress or see more technical details, check the linked issues and discussions. <!-- 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/cc9d65bb-6c59-42c5-89ed-ebc641712d17?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/cc9d65bb-6c59-42c5-89ed-ebc641712d17?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/cc9d65bb-6c59-42c5-89ed-ebc641712d17?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/cc9d65bb-6c59-42c5-89ed-ebc641712d17?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/cc9d65bb-6c59-42c5-89ed-ebc641712d17?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/cc9d65bb-6c59-42c5-89ed-ebc641712d17?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/cc9d65bb-6c59-42c5-89ed-ebc641712d17?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%20is%20a%20known%20regression%20in%20Better%20Auth%20v1.4.x%3A%20fields%20defined%20as%20%60string%5B%5D%60%20in%20%60user.additionalFields%60%20are%20now%20stored%20as%20JSON%20strings%20%28e.g.%2C%20%60%22%5B%5C%22CONTRIBUTOR%5C%22%5D%22%60%29%20instead%20of%20native%20arrays%20in%20the%20database.%20This%20change%20affects%20multiple%20adapters%2C%20including%20MongoDB%2C%20and%20is%20due%20to%20upstream%20changes%20in%20validation%20and%20serialization%20logic%E2%80%94not%20the%20MongoDB%20adapter%20itself%2C%20which%20expects%20arrays%20and%20does%20not%20stringify%20them.%20The%20conversion%20to%20string%20happens%20earlier%20in%20the%20pipeline%2C%20likely%20when%20a%20validator%20is%20present%20or%20due%20to%20how%20additional%20fields%20are%20processed%20after%20v1.4.0%20%5B%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/issues/6779%23issuecomment-3656323266%29%5D.%0A%0AThere%20is%20currently%20no%20config%20option%20to%20force%20native%20array%20storage%20for%20%60string%5B%5D%60%20fields.%20Workarounds%20for%20other%20databases%20involve%20editing%20migration%20logic%2C%20but%20for%20MongoDB%2C%20the%20only%20known%20workaround%20is%20to%20temporarily%20remove%20any%20validators%20on%20the%20affected%20field%20%28if%20present%29%2C%20which%20may%20allow%20arrays%20to%20be%20stored%20natively%20again%20%5B%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/issues/6482%23issuecomment-3633671216%29%5D.%20If%20you%20must%20use%20validators%2C%20you%20may%20need%20to%20manually%20parse%20the%20string%20back%20into%20an%20array%20when%20reading%20from%20the%20database.%0A%0AThis%20is%20a%20recent%20and%20widely%20reported%20issue%2C%20and%20the%20maintainers%20are%20aware.%20If%20you%20need%20to%20track%20progress%20or%20see%20more%20technical%20details%2C%20check%20the%20linked%20issues%20and%20discussions.)&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/6975)
Author
Owner

@bytaesu commented on GitHub (Dec 24, 2025):

Hi @firatciftci, I'm checking this!

<!-- gh-comment-id:3689837208 --> @bytaesu commented on GitHub (Dec 24, 2025): Hi @firatciftci, I'm checking 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#19320