[GH-ISSUE #3126] Sign up additionalFields with array type items gets duplicated when using before hooks #18113

Closed
opened 2026-04-15 16:29:42 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @sabvente on GitHub (Jun 22, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/3126

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

const auth = betterAuth({
  user: {
    additionalFields: {
      tags: {
        type: "string[]",
        required: true
      }
    }
  },
  hooks: {
    before: createAuthMiddleware(async (ctx) => {
      if (ctx.path !== "/sign-up/email") {
        return
      }
      return {
        context: {
          ...ctx,
          body: {
            ...ctx.body,
            someOtherField: "someValue", // Example of additional field
          },
        }
      }
    }),
  },
})

Current vs. Expected behavior

tags array gets duplicated in the database (might affect other features)

defu dependency concatenates array values by default
See sample:

console.log(defu({ array: ["b", "c"] }, { array: ["a"] }));
// => { array: ['b', 'c', 'a'] }

Problematic code in better-auth source:
2fe1be0e5f/packages/better-auth/src/api/to-auth-endpoints.ts (L73)

Or here:
2fe1be0e5f/packages/better-auth/src/api/to-auth-endpoints.ts (L157)

Expected: I expect array items to not get duplicated.

What version of Better Auth are you using?

1.2.7

Provide environment information

chrome

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

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth"
export const auth = betterAuth({
  emailAndPassword: {  
    enabled: true
  },
});

Additional context

No response

Originally created by @sabvente on GitHub (Jun 22, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/3126 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce ```js const auth = betterAuth({ user: { additionalFields: { tags: { type: "string[]", required: true } } }, hooks: { before: createAuthMiddleware(async (ctx) => { if (ctx.path !== "/sign-up/email") { return } return { context: { ...ctx, body: { ...ctx.body, someOtherField: "someValue", // Example of additional field }, } } }), }, }) ``` ### Current vs. Expected behavior `tags` array gets duplicated in the database (might affect other features) `defu` dependency concatenates array values by default See sample: ``` console.log(defu({ array: ["b", "c"] }, { array: ["a"] })); // => { array: ['b', 'c', 'a'] } ``` Problematic code in better-auth source: https://github.com/better-auth/better-auth/blob/2fe1be0e5f023be77b07206dd960f9fd38abba8c/packages/better-auth/src/api/to-auth-endpoints.ts#L73 Or here: https://github.com/better-auth/better-auth/blob/2fe1be0e5f023be77b07206dd960f9fd38abba8c/packages/better-auth/src/api/to-auth-endpoints.ts#L157 Expected: I expect array items to not get duplicated. ### What version of Better Auth are you using? 1.2.7 ### Provide environment information ```bash chrome ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ emailAndPassword: { enabled: true }, }); ``` ### Additional context _No response_
GiteaMirror added the lockedbug labels 2026-04-15 16:29:42 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Jun 22, 2025):

This is a confirmed bug in Better Auth v1.2.7: array-type additionalFields (like tags) get duplicated because the code uses the defu library, which concatenates arrays by default when merging objects. This affects both sign-up and update flows, so arrays like tags will keep growing with repeated or merged values instead of being replaced as expected. The problematic code is in the merging logic of to-auth-endpoints.ts, as you pointed out (source).

There’s currently no built-in way to change this behavior or configure array merging in Better Auth, and no official documentation or hooks to override it. No recent pull requests or issues address this yet.

Workarounds:

  • Pre-process your input to ensure arrays are deduplicated before passing them to Better Auth.
  • Post-process the saved data to remove duplicates after sign-up/update.
  • As a last resort, you could monkey-patch defu or wrap your Better Auth usage with a custom merge function that replaces arrays instead of merging, but this is brittle and not officially supported.

If you need this fixed in the framework, you’ll need to watch for updates or request a feature to allow custom array merge strategies. For now, manual deduplication is the safest workaround.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Join Discord Share on X

<!-- gh-comment-id:2994057955 --> @dosubot[bot] commented on GitHub (Jun 22, 2025): <!-- Answer --> This is a confirmed bug in Better Auth v1.2.7: array-type additionalFields (like tags) get duplicated because the code uses the defu library, which concatenates arrays by default when merging objects. This affects both sign-up and update flows, so arrays like tags will keep growing with repeated or merged values instead of being replaced as expected. The problematic code is in the merging logic of to-auth-endpoints.ts, as you pointed out ([source](https://github.com/better-auth/better-auth/blob/2fe1be0e5f023be77b07206dd960f9fd38abba8c/packages/better-auth/src/api/to-auth-endpoints.ts)). There’s currently no built-in way to change this behavior or configure array merging in Better Auth, and no official documentation or hooks to override it. No recent pull requests or issues address this yet. Workarounds: - Pre-process your input to ensure arrays are deduplicated before passing them to Better Auth. - Post-process the saved data to remove duplicates after sign-up/update. - As a last resort, you could monkey-patch defu or wrap your Better Auth usage with a custom merge function that replaces arrays instead of merging, but this is brittle and not officially supported. If you need this fixed in the framework, you’ll need to watch for updates or request a feature to allow custom array merge strategies. For now, manual deduplication is the safest workaround. <!-- 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/3daa17bb-5149-4771-8dcc-c3525972120d?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/3daa17bb-5149-4771-8dcc-c3525972120d?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/3daa17bb-5149-4771-8dcc-c3525972120d?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/3daa17bb-5149-4771-8dcc-c3525972120d?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/3daa17bb-5149-4771-8dcc-c3525972120d?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/3daa17bb-5149-4771-8dcc-c3525972120d?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/3daa17bb-5149-4771-8dcc-c3525972120d?feedback_type=other)</sup>&nbsp;&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/3126)
Author
Owner

@sabvente commented on GitHub (Jun 22, 2025):

Workaround:

If you don't need to modify the array in the hook, remove the property from the returned context, so it won't be concatenated (duplicated).

hooks: {
  before: createAuthMiddleware(async (ctx) => {
    if (ctx.path !== "/sign-up/email") {
      return
    }
    const { tags, ...newBody } = ctx.body
    return {
      context: {
        ...ctx,
        body: newBody,
      }
    }
  }),
},
<!-- gh-comment-id:2994062528 --> @sabvente commented on GitHub (Jun 22, 2025): Workaround: If you don't need to modify the array in the hook, remove the property from the returned context, so it won't be concatenated (duplicated). ```js hooks: { before: createAuthMiddleware(async (ctx) => { if (ctx.path !== "/sign-up/email") { return } const { tags, ...newBody } = ctx.body return { context: { ...ctx, body: newBody, } } }), }, ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#18113