[GH-ISSUE #7990] A web of issues related to plugins' additionalFields' required property and its default value #28288

Closed
opened 2026-04-17 19:43:35 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @JeffreyLind3 on GitHub (Feb 16, 2026).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/7990

Current vs. Expected behavior

In the Better Auth plugin documentation (https://www.better-auth.com/docs/concepts/plugins#schema), it says that the default value for the required field in additional fields is false. However, I did a best-effort search within the codebase as much as I could understand + did some testing in my application, and not explicitly providing required: false forces those additional fields to be required, contradicting the documentation.

Just for context, I am working with the Organization plugin, so maybe this is an oddity with that plugin that does not contradict with the more general plugins documentation, so not sure.

Can see in my Better Auth configuration below, that if I remove, for example, required: false from description, and try to create an organization without a description provided, an error is thrown.

What version of Better Auth are you using?

1.4.18

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

Documentation

Auth config (if applicable)

plugins: [
    organization({
      ac,
      roles: { owner, member },
      organizationLimit: 1,
      requireEmailVerificationOnInvitation: true,
      sendInvitationEmail: async (data) => {
        after(() =>
          resend.emails.send({
            from: FROM_EMAIL,
            to: data.email,
            subject: "placeholder",
            react: InviteMemberTemplate({
              url: `${env.BETTER_AUTH_URL}/sign-up`,
            }),
          }),
        );
      },
      schema: {
        organization: {
          additionalFields: {
            email: { type: "string", required: false },
            phone: { type: "string", required: false },
            website: { type: "string", required: false },
            description: { type: "string", required: false },
          },
        },
      },
    }),
    nextCookies(), // nextCookies() MUST be the last element of the array
  ],
Originally created by @JeffreyLind3 on GitHub (Feb 16, 2026). Original GitHub issue: https://github.com/better-auth/better-auth/issues/7990 ### Current vs. Expected behavior In the Better Auth plugin documentation (https://www.better-auth.com/docs/concepts/plugins#schema), it says that the default value for the `required` field in additional fields is `false`. However, I did a best-effort search within the codebase as much as I could understand + did some testing in my application, and not explicitly providing `required: false` forces those additional fields to be required, contradicting the documentation. Just for context, I am working with the Organization plugin, so maybe this is an oddity with that plugin that does not contradict with the more general plugins documentation, so not sure. Can see in my Better Auth configuration below, that if I remove, for example, `required: false` from `description`, and try to create an organization without a `description` provided, an error is thrown. ### What version of Better Auth are you using? 1.4.18 ### Which area(s) are affected? (Select all that apply) Documentation ### Auth config (if applicable) ```typescript plugins: [ organization({ ac, roles: { owner, member }, organizationLimit: 1, requireEmailVerificationOnInvitation: true, sendInvitationEmail: async (data) => { after(() => resend.emails.send({ from: FROM_EMAIL, to: data.email, subject: "placeholder", react: InviteMemberTemplate({ url: `${env.BETTER_AUTH_URL}/sign-up`, }), }), ); }, schema: { organization: { additionalFields: { email: { type: "string", required: false }, phone: { type: "string", required: false }, website: { type: "string", required: false }, description: { type: "string", required: false }, }, }, }, }), nextCookies(), // nextCookies() MUST be the last element of the array ], ```
GiteaMirror added the locked label 2026-04-17 19:43:35 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Feb 16, 2026):

You've found a real documentation bug. The documentation states that required defaults to false, but the code actually defaults to true.

The DBFieldAttributeConfig type has a JSDoc annotation showing @default true:

export type DBFieldAttributeConfig = {
	/**
	 * If the field should be required on a new record.
	 * @default true
	 */
	required?: boolean | undefined;
	// ...
}

This is also enforced at runtime in parseInputData, which throws an error for missing required fields during create operations.

For the Organization plugin specifically, additional fields are merged directly without modification, so they inherit this default required: true behavior.

Your workaround of explicitly setting required: false is correct — the documentation should be updated to reflect that the default is actually true.

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:3906621188 --> @dosubot[bot] commented on GitHub (Feb 16, 2026): <!-- Answer --> You've found a real documentation bug. The [documentation](https://www.better-auth.com/docs/concepts/plugins#schema) states that `required` defaults to `false`, but the code actually defaults to `true`. The [`DBFieldAttributeConfig` type](https://github.com/better-auth/better-auth/blob/d3b579e42a707a9037a9210ad14611366b745d2a/packages/core/src/db/type.ts#L31-L36) has a JSDoc annotation showing `@default true`: ```typescript export type DBFieldAttributeConfig = { /** * If the field should be required on a new record. * @default true */ required?: boolean | undefined; // ... } ``` This is also enforced at runtime in [`parseInputData`](https://github.com/better-auth/better-auth/blob/d3b579e42a707a9037a9210ad14611366b745d2a/packages/better-auth/src/db/schema.ts#L175-L179), which throws an error for missing required fields during create operations. For the Organization plugin specifically, additional fields are [merged directly](https://github.com/better-auth/better-auth/blob/d3b579e42a707a9037a9210ad14611366b745d2a/packages/better-auth/src/plugins/organization/organization.ts#L1075) without modification, so they inherit this default `required: true` behavior. **Your workaround of explicitly setting `required: false` is correct** — the documentation should be updated to reflect that the default is actually `true`. <!-- 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/a60b7981-c4d0-464e-9584-dfbcc0c143fa?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/a60b7981-c4d0-464e-9584-dfbcc0c143fa?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/a60b7981-c4d0-464e-9584-dfbcc0c143fa?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/a60b7981-c4d0-464e-9584-dfbcc0c143fa?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/a60b7981-c4d0-464e-9584-dfbcc0c143fa?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/a60b7981-c4d0-464e-9584-dfbcc0c143fa?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/a60b7981-c4d0-464e-9584-dfbcc0c143fa?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=You%27ve%20found%20a%20real%20documentation%20bug.%20The%20%5Bdocumentation%5D%28https%3A//www.better-auth.com/docs/concepts/plugins%23schema%29%20states%20that%20%60required%60%20defaults%20to%20%60false%60%2C%20but%20the%20code%20actually%20defaults%20to%20%60true%60.%0A%0AThe%20%5B%60DBFieldAttributeConfig%60%20type%5D%28https%3A//github.com/better-auth/better-auth/blob/d3b579e42a707a9037a9210ad14611366b745d2a/packages/core/src/db/type.ts%23L31-L36%29%20has%20a%20JSDoc%20annotation%20showing%20%60%40default%20true%60%3A%0A%0A%60%60%60typescript%0Aexport%20type%20DBFieldAttributeConfig%20%3D%20%7B%0A%09/%2A%2A%0A%09%20%2A%20If%20the%20field%20should%20be%20required%20on%20a%20new%20record.%0A%09%20%2A%20%40default%20true%0A%09%20%2A/%0A%09required%3F%3A%20boolean%20%7C%20undefined%3B%0A%09//%20...%0A%7D%0A%60%60%60%0A%0AThis%20is%20also%20enforced%20at%20runtime%20in%20%5B%60parseInputData%60%5D%28https%3A//github.com/better-auth/better-auth/blob/d3b579e42a707a9037a9210ad14611366b745d2a/packages/better-auth/src/db/schema.ts%23L175-L179%29%2C%20which%20throws%20an%20error%20for%20missing%20required%20fields%20during%20create%20operations.%0A%0AFor%20the%20Organization%20plugin%20specifically%2C%20additional%20fields%20are%20%5Bmerged%20directly%5D%28https%3A//github.com/better-auth/better-auth/blob/d3b579e42a707a9037a9210ad14611366b745d2a/packages/better-auth/src/plugins/organization/organization.ts%23L1075%29%20without%20modification%2C%20so%20they%20inherit%20this%20default%20%60required%3A%20true%60%20behavior.%0A%0A%2A%2AYour%20workaround%20of%20explicitly%20setting%20%60required%3A%20false%60%20is%20correct%2A%2A%20%E2%80%94%20the%20documentation%20should%20be%20updated%20to%20reflect%20that%20the%20default%20is%20actually%20%60true%60.)&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/7990)
Author
Owner

@JeffreyLind3 commented on GitHub (Feb 16, 2026):

New finding: whenever the required property is not set at all, it defaults to true in terms of the logic, but the type inference system still considers that field optional as far as I can find.

For example, you can reproduce it by first considering my auth config provided in the original message above.

Then, if you have description: { type: "string", required: true }, then, for example, auth.api.getFullOrganization has a return type with description: string (this is correct).

However, if you do description: { type: "string" }, the application logic acts as if you have required: true set (correct), but auth.api.getFullOrganization, for example, has a return type with description?: string | undefined (incorrect)

So, seems to be some deeper issues here beyond just a documentation issue.

<!-- gh-comment-id:3906709169 --> @JeffreyLind3 commented on GitHub (Feb 16, 2026): New finding: whenever the required property is not set at all, it defaults to true in terms of the logic, but the type inference system still considers that field optional as far as I can find. For example, you can reproduce it by first considering my auth config provided in the original message above. Then, if you have `description: { type: "string", required: true }`, then, for example, `auth.api.getFullOrganization` has a return type with `description: string` (this is correct). However, if you do `description: { type: "string" }`, the application logic acts as if you have `required: true` set (correct), but `auth.api.getFullOrganization`, for example, has a return type with `description?: string | undefined` (incorrect) So, seems to be some deeper issues here beyond just a documentation issue.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#28288