Skip to content

fix: loosens email signup body schema to throw correct error code - #11199

Open
mathewmeconry wants to merge 112 commits into
better-auth:nextfrom
mathewmeconry:fix/loosen_api_validation
Open

fix: loosens email signup body schema to throw correct error code#11199
mathewmeconry wants to merge 112 commits into
better-auth:nextfrom
mathewmeconry:fix/loosen_api_validation

Conversation

@mathewmeconry

@mathewmeconry mathewmeconry commented Sep 7, 2026

Copy link
Copy Markdown

Summary
Align error response codes for email validation across authentication endpoints to allow granular client-side error handling.

Problem
The endpoints /api/auth/sign-up/email and /api/auth/change-email currently fail schema validation at the request body layer, returning a generic VALIDATION_ERROR. This prevents clients from catching specific validation issues and presenting user-friendly error messages (e.g., distinguishing between a missing required field and an ill-formed email address or showing a correct translation of the error).

Current Response:

{
    "code": "VALIDATION_ERROR",
    "message": "Validation error",
    "originalMessage": "[body.email] Invalid email address"
}

Solution

  • Loosened the body schema for these endpoints to validate the payload as a string rather than enforcing strict email format rules at the schema layer.
  • Moved email format verification directly into the endpoint implementation logic (matching the pattern used by other auth endpoints).
  • Updated error responses to return a specific INVALID_EMAIL error code upon failure.

New Response:

{
    "code": "INVALID_EMAIL",
    "message": "Ungültige E-Mail-Adresse",
    "originalMessage": "Invalid email"
}

Summary by cubic

Changes email validation on the sign-up and change-email endpoints to return a specific INVALID_EMAIL error code instead of the generic VALIDATION_ERROR, so clients can distinguish an ill-formed email from other validation failures.

  • Loosens the request body schema to accept any non-empty string for the email field.
  • Moves email format verification into the endpoint logic, matching other auth endpoints.
  • Endpoints now return a single error at a time instead of an array of all validation errors.

Written for commit 1aa74fb. Summary will update on new commits.

Review in cubic

gustavovalverde and others added 30 commits August 17, 2026 20:03
chore: promote v1.7.0 to stable
…better-auth#10879)

Co-authored-by: starslingdev[bot] <248995740+starslingdev[bot]@users.noreply.github.com>
Co-authored-by: Taesu <bytaesu@gmail.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
…ter-auth#7516)

Co-authored-by: Arthur Zhang <a8zhang@uwaterloo.ca>
Co-authored-by: Taesu <bytaesu@gmail.com>
Copilot AI lite review requested due to automatic review settings September 7, 2026 13:30
@mathewmeconry
mathewmeconry requested a review from a team as a code owner September 7, 2026 13:30
@mathewmeconry
mathewmeconry requested review from Bekacru and removed request for a team September 7, 2026 13:30
@vercel

vercel Bot commented Sep 7, 2026

Copy link
Copy Markdown

@mathewmeconry is attempting to deploy a commit to the better-auth Team on Vercel.

A member of the Team first needs to authorize it.

@better-release better-release Bot added the core Core infra, API routes, session, cookies, client SDK label Sep 7, 2026
@better-release
better-release Bot changed the base branch from main to next September 7, 2026 13:31
@better-release
better-release Bot requested review from a team as code owners September 7, 2026 13:31
@better-release
better-release Bot requested review from gustavovalverde and removed request for a team September 7, 2026 13:31
@better-release

better-release Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

This PR was automatically retargeted from main to next because it contains a minor changeset. The main branch only accepts patch (bug fix) changes. Features and breaking changes go through next for beta testing before promotion to stable.

@socket-security

socket-security Bot commented Sep 7, 2026

Copy link
Copy Markdown

@mathewmeconry

mathewmeconry commented Sep 7, 2026

Copy link
Copy Markdown
Author

I am not 100% sure if this is going to be a patch or a minor because it changes the behaviour of an endpoint. The bot automatically changed it to next, while I branched off from the main branch

@greptile-apps

greptile-apps Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Too many files changed for review (640 files, 100 file limit).

@mathewmeconry
mathewmeconry force-pushed the fix/loosen_api_validation branch from 1c8d98e to 1aa74fb Compare September 7, 2026 13:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The diff includes broad, cross-cutting changes (core account identity/schema behavior, new schema validation flow, tooling/docs/CI refactors) beyond the stated email-validation fix and needs careful human migration/compatibility review.

Pull request overview

This pull request updates Better Auth across multiple packages and subsystems. While the PR metadata focuses on aligning email-validation error codes (returning INVALID_EMAIL instead of schema-layer VALIDATION_ERROR), the diff also includes broad changes to account identity modeling (removing issuer), runtime database schema validation, new release tooling, test utilities, docs/navigation restructuring, and a coordinated version bump to 1.7.3.

Changes:

  • Loosened request-body email validation for /sign-up/email by accepting a string at the schema layer and enforcing email format inside endpoint logic (to return INVALID_EMAIL).
  • Removed issuer from account identity/schema and updated related code/tests/docs to use (providerId, accountId) as the stable account key.
  • Added/extended tooling and infra: runtime schema checks (Kysely/Drizzle/Prisma), new release-tooling package, docs versioning/LLMs routes, CI workflow tweaks, and package version/dependency normalization (e.g. zod: "catalog:").
File summaries
File Description
turbo.json Adjust docs build inputs/outputs and env passthrough for Turbo caching.
tsconfig.json Add packages/release-tooling project reference.
tsconfig.dist-check.json Include packages/release-tooling/src/** in dist checks.
test/unit/types/db.test.ts Update type expectations after account schema changes (remove issuer).
packages/test-utils/vitest.config.ts Add Vitest project config for @better-auth/test-utils.
packages/test-utils/src/adapter/cleanup.ts Add adapter cleanup helper for tracked rows with retry support.
packages/test-utils/package.json Bump version and add test script.
packages/telemetry/package.json Bump package version to 1.7.3.
packages/telemetry/CHANGELOG.md Add changelog headings for 1.7.11.7.3.
packages/stripe/test/seat-based-billing.test.ts Remove issuer usage from test fixtures.
packages/stripe/package.json Bump version and switch zod dependency to catalog.
packages/stripe/CHANGELOG.md Add changelog headings for 1.7.11.7.3.
packages/sso/src/routes/saml-pipeline.ts Remove issuer field when creating account records.
packages/sso/src/providers.test.ts Remove issuer expectations in SSO provider tests.
packages/sso/package.json Bump version, update @xmldom/xmldom, switch zod to catalog.
packages/scim/src/scim-sso-http-e2e.test.ts Remove issuer expectations in SCIM SSO e2e tests.
packages/scim/src/scim-managed-connections.test.ts Expand invalid creationRequestId test cases.
packages/scim/package.json Bump version and switch zod dependency to catalog.
packages/scim/CHANGELOG.md Add changelog headings for 1.7.11.7.3.
packages/release-tooling/vitest.config.ts Add Vitest project config for release tooling.
packages/release-tooling/turbo.json Add Turbo task config for release-tooling test inputs.
packages/release-tooling/tsconfig.json Add TS config for NodeNext-based release-tooling package.
packages/release-tooling/test/actions-output.test.ts Add tests for GitHub Actions output logging behavior.
packages/release-tooling/src/release-notes/review.prompt.md Add prompt template for reviewing release-note rewrites.
packages/release-tooling/src/release-notes/repair.prompt.md Add prompt template for repairing rejected release-note rewrites.
packages/release-tooling/src/git.ts Add git command helpers with timeouts/buffers.
packages/release-tooling/src/conventional-header.ts Add conventional-commit header parser utility.
packages/release-tooling/src/commands/auto-changeset.ts Add command wiring for auto changeset recommendation.
packages/release-tooling/src/command.ts Add reusable command runner with error handling and exit code.
packages/release-tooling/src/changesets/rewrite.prompt.md Add prompt template for changeset description rewriting.
packages/release-tooling/src/ai/models.ts Define model selection for changeset/release-notes generation and review.
packages/release-tooling/src/actions-output.ts Add setOutput wrapper to avoid leaking values to logs.
packages/redis-storage/vitest.config.ts Add Vitest project config for redis-storage package.
packages/redis-storage/README.md Update docs link for Redis Storage concept page.
packages/redis-storage/package.json Bump version and update homepage/docs link.
packages/redis-storage/CHANGELOG.md Add changelog headings for 1.7.11.7.3.
packages/prisma-adapter/src/prisma-adapter.ts Register runtime schema checks during adapter initialization.
packages/prisma-adapter/package.json Bump version to 1.7.3.
packages/prisma-adapter/CHANGELOG.md Add detailed changelog entry for schema validation behavior.
packages/passkey/src/passkey.test.ts Add test to reject registration without required response payload.
packages/passkey/src/open-api.test.ts Assert OpenAPI marks response as required for registration verification.
packages/passkey/package.json Bump version and switch zod to catalog.
packages/passkey/CHANGELOG.md Add changelog headings for 1.7.11.7.3.
packages/oauth-provider/src/register.ts Adjust grant type validation rules for metadata documents vs non-metadata.
packages/oauth-provider/src/authorize.test.ts Add test coverage for formatErrorURL behavior.
packages/oauth-provider/package.json Bump version and switch zod to catalog.
packages/mongo-adapter/package.json Bump version to 1.7.3.
packages/mongo-adapter/CHANGELOG.md Add changelog headings for 1.7.11.7.3.
packages/memory-adapter/package.json Bump version to 1.7.3.
packages/memory-adapter/CHANGELOG.md Add changelog headings for 1.7.11.7.3.
packages/mcp/package.json Bump version to 1.7.3.
packages/mcp/CHANGELOG.md Update dependency notes for @better-auth/oauth-provider.
packages/kysely-adapter/src/types.ts Add normalized index metadata/introspection types.
packages/kysely-adapter/src/index.ts Export schema-check helpers publicly.
packages/kysely-adapter/package.json Bump version and add pg + @types/pg dev deps.
packages/kysely-adapter/CHANGELOG.md Add changelog entry for runtime schema validation behavior.
packages/i18n/package.json Bump version to 1.7.3.
packages/i18n/CHANGELOG.md Add changelog headings for 1.7.11.7.3.
packages/expo/package.json Bump version and switch zod to catalog.
packages/expo/CHANGELOG.md Add changelog entry for Expo cookie write coordination behavior.
packages/electron/package.json Bump version and switch zod to catalog.
packages/electron/CHANGELOG.md Add changelog headings for 1.7.11.7.3.
packages/drizzle-adapter/package.json Bump version to 1.7.3.
packages/core/src/utils/ip.test.ts Add additional invalid IP cases.
packages/core/src/types/init-options.ts Document advanced.database.validateSchema option (default true).
packages/core/src/types/context.ts Add optional checkSchema to auth context type.
packages/core/src/social-providers/wechat.ts Switch to namespaced placeholder email helper.
packages/core/src/social-providers/twitter.ts Switch to namespaced placeholder email helper.
packages/core/src/social-providers/social-providers.test.ts Remove tests tied to accountIssuer behavior.
packages/core/src/social-providers/roblox.ts Use placeholder email helper for Roblox provider.
packages/core/src/social-providers/roblox.test.ts Add tests for Roblox placeholder email behavior.
packages/core/src/social-providers/paybin.ts Remove accountIssuer wiring.
packages/core/src/social-providers/microsoft-entra-id.ts Remove accountIssuer resolver.
packages/core/src/social-providers/line.ts Remove accountIssuer constant.
packages/core/src/social-providers/index.ts Add cloudflare provider export/registration.
packages/core/src/social-providers/google.ts Remove accountIssuer constant.
packages/core/src/social-providers/facebook.ts Remove accountIssuer constant.
packages/core/src/social-providers/cognito.ts Remove accountIssuer constant.
packages/core/src/social-providers/apple.ts Remove accountIssuer constant.
packages/core/src/oauth2/oauth-provider.ts Remove accountIssuer from OAuth provider interface.
packages/core/src/oauth2/index.ts Export token-endpoint request hook/context types.
packages/core/src/env/logger.ts Route default logger calls through endpoint context when available.
packages/core/src/db/schema/user.ts Update inline comment to refer to (providerId, accountId) identity keying.
packages/core/src/db/schema/account.ts Remove issuer from schema and redefine AccountKey as (providerId, accountId).
packages/core/src/db/internal.ts Export schema-check and schema-diff internal utilities.
packages/core/src/db/index.ts Stop exporting issuer helpers removed from account schema.
packages/core/src/db/get-tables.ts Remove default unique index and required issuer column definition for accounts.
packages/core/src/context/transaction.ts Ensure schema check settles before starting a transaction that may hold a single connection.
packages/core/src/context/index.ts Export endpoint-context getters.
packages/core/src/context/global.ts Add helper to access current endpoint context from async storage.
packages/core/package.json Bump version and switch zod to catalog; adjust conditional export ordering.
packages/cli/test/migrate.test.ts Use a serving auth instance for signup in migrate tests.
packages/cli/test/snapshots/schema.prisma Remove issuer and (issuer, accountId) unique index from Prisma snapshot.
packages/cli/test/snapshots/schema-uuid.prisma Remove issuer and (issuer, accountId) unique index from Prisma snapshot.
packages/cli/test/snapshots/schema-prisma-use-plural.prisma Remove issuer and (issuer, accountId) unique index from plural Prisma snapshot.
packages/cli/test/snapshots/schema-numberid.prisma Remove issuer and (issuer, accountId) unique index from number-id Prisma snapshot.
packages/cli/test/snapshots/schema-mysql.prisma Remove issuer, adjust MySQL column types, remove unique index snapshot.
packages/cli/test/snapshots/schema-mysql-custom.prisma Remove issuer, adjust MySQL column types, remove unique index snapshot.
packages/cli/test/snapshots/schema-mongodb.prisma Remove issuer and unique index from MongoDB Prisma snapshot.
packages/cli/test/snapshots/auth-schema.txt Remove issuer column and unique index from generated Drizzle schema snapshot.
packages/cli/test/snapshots/auth-schema-pg-with-schema-name.txt Remove issuer column and unique index from schema-name snapshot.
packages/cli/test/snapshots/auth-schema-pg-uuid.txt Remove issuer column and unique index from uuid snapshot.
packages/cli/test/snapshots/auth-schema-pg-passkey.txt Remove issuer column and unique index from passkey snapshot.
packages/cli/test/snapshots/auth-schema-number-id.txt Remove issuer column and unique index from number-id snapshot.
packages/cli/test/snapshots/auth-schema-mysql.txt Remove issuer column and unique index from MySQL snapshot.
packages/cli/test/snapshots/auth-schema-mysql-uuid.txt Remove issuer column and unique index from MySQL uuid snapshot.
packages/cli/test/snapshots/auth-schema-mysql-passkey.txt Remove issuer column and unique index from MySQL passkey snapshot.
packages/cli/test/snapshots/auth-schema-mysql-passkey-number-id.txt Remove issuer column and unique index from MySQL passkey+number snapshot.
packages/cli/test/snapshots/auth-schema-mysql-number-id.txt Remove issuer column and unique index from MySQL number-id snapshot.
packages/cli/test/snapshots/auth-schema-mysql-enum.txt Remove issuer column and unique index from MySQL enum snapshot.
packages/cli/test/snapshots/auth-schema-multi-relation.txt Remove issuer and unique index; simplify imports.
packages/cli/test/snapshots/auth-schema-duplicate-relations.txt Remove issuer and unique index; simplify imports.
packages/cli/src/utils/install-dependencies.ts Handle empty dependency list and improve error messaging with causes.
packages/cli/src/index.ts Use async commander parse and improve BetterAuthError handling output.
packages/cli/src/generators/types.ts Add generator result fields for unsafe changes and schema problems.
packages/cli/src/generators/index.ts Type generator output as SchemaGeneratorResult.
packages/cli/src/commands/init/configs/temp-plugins.config.ts Update SIWE email domain option description.
packages/cli/src/commands/init/configs/social-providers.config.ts Add Cloudflare provider env config.
packages/cli/src/commands/generate.ts Warn about schema problems / unsafe schema changes during generation.
packages/cli/package.json Bump version and switch zod to catalog.
packages/cimd/src/node.ts Fix Node DNS lookup callback behavior for all: true address selection.
packages/cimd/package.json Bump version to 1.7.3.
packages/cimd/CHANGELOG.md Add changelog entry for Node ERR_INVALID_IP_ADDRESS fix.
packages/better-auth/src/plugins/username/username.test.ts Remove issuer field usage in test setup.
packages/better-auth/src/plugins/two-factor/error-code.ts Add TOTP_ALREADY_ENABLED error code.
packages/better-auth/src/plugins/phone-number/routes.ts Remove createLocalAccountIssuer usage when creating credential account.
packages/better-auth/src/plugins/phone-number/phone-number.test.ts Remove issuer expectations in phone-number tests.
packages/better-auth/src/plugins/organization/has-permission.ts Reuse zod schema for role permissions parsing and improve logging payload reuse.
packages/better-auth/src/plugins/one-tap/one-tap.test.ts Remove issuer usage from fixtures/queries.
packages/better-auth/src/plugins/one-tap/index.ts Remove issuer field when linking one-tap accounts.
packages/better-auth/src/plugins/magic-link/magic-link.test.ts Remove issuer usage from fixture account creation.
packages/better-auth/src/plugins/last-login-method/index.ts Track email-OTP sign-in path as a last-login-method.
packages/better-auth/src/plugins/jwt/verify.ts Use endpoint context getter (sync) instead of async auth context.
packages/better-auth/src/plugins/generic-oauth/types.ts Remove accountIssuer config option.
packages/better-auth/src/plugins/generic-oauth/providers/slack.ts Remove accountIssuer constant.
packages/better-auth/src/plugins/generic-oauth/providers/okta.ts Remove accountIssuer wiring.
packages/better-auth/src/plugins/generic-oauth/providers/line.ts Remove accountIssuer constant.
packages/better-auth/src/plugins/generic-oauth/providers/keycloak.ts Remove accountIssuer wiring.
packages/better-auth/src/plugins/generic-oauth/providers/auth0.ts Normalize domain parsing via URL and remove accountIssuer wiring.
packages/better-auth/src/plugins/email-otp/routes.ts Remove createLocalAccountIssuer usage in reset-password flow.
packages/better-auth/src/plugins/email-otp/email-otp.test.ts Remove issuer expectations in tests.
packages/better-auth/src/plugins/anonymous/types.ts Update anonymous email domain option docs/default value.
packages/better-auth/src/plugins/anonymous/index.ts Use placeholder email helper for anonymous users.
packages/better-auth/src/plugins/anonymous/anon.test.ts Add test asserting default placeholder email namespace.
packages/better-auth/src/oauth2/state.ts Treat empty errorURL as absent when selecting redirect target.
packages/better-auth/src/oauth2/errors.ts Use appendQueryParams to build redirect URLs and adjust wording.
packages/better-auth/src/oauth2/account-key.ts Resolve OAuth account key using (providerId, accountId) instead of issuer logic.
packages/better-auth/src/db/adapter-kysely.ts Consolidate dynamic imports and clean up adapter construction.
packages/better-auth/src/cookies/cache.ts Add warning log when cookie-cache payload fails schema validation.
packages/better-auth/src/context/init-minimal.test.ts Add test verifying registered schema checks are exposed on minimal context.
packages/better-auth/src/context/create-context.ts Attach adapter schema check to created context.
packages/better-auth/src/client/vanilla.ts Reformat hydrateSession type signature.
packages/better-auth/src/client/svelte/index.ts Reformat hydrateSession type signature.
packages/better-auth/src/client/solid/index.ts Reformat hydrateSession type signature.
packages/better-auth/src/client/react/index.ts Reformat hydrateSession type signature.
packages/better-auth/src/client/lynx/index.ts Reformat hydrateSession type signature.
packages/better-auth/src/client/config.ts Include $sessionSignal in returned client config.
packages/better-auth/src/client/client.test.ts Add type regression test for plugin assignability.
packages/better-auth/src/api/to-auth-endpoints.ts Ensure schema check settles before executing endpoint handler.
packages/better-auth/src/api/routes/update-user.test.ts Remove issuer expectations in credential identity tests.
packages/better-auth/src/api/routes/sign-up.ts Loosen request schema email validation and remove issuer usage when linking account.
packages/better-auth/src/api/routes/sign-up.test.ts Remove issuer field mapping from custom account fields config.
packages/better-auth/src/api/routes/sign-out.test.ts Remove issuer usage from OAuth account fixtures.
packages/better-auth/src/api/routes/sign-in.ts Remove issuer-dependent credential account lookup; adjust social account creation.
packages/better-auth/src/api/routes/password.ts Remove createLocalAccountIssuer usage when creating credential account.
packages/better-auth/src/api/routes/password.test.ts Remove issuer expectations in password reset tests.
packages/better-auth/src/api/routes/email-verification.ts Use appendQueryParams for callback redirect error propagation.
packages/better-auth/src/api/index.ts Ensure schema check settles before routing request.
packages/better-auth/package.json Bump version, switch zod to catalog, and normalize vitest catalog usage.
packages/api-key/package.json Bump version and switch zod to catalog.
packages/api-key/CHANGELOG.md Add changelog headings for 1.7.11.7.3.
package.json Add pkg-pr-new dev dependency.
knip.jsonc Adjust ignores and add knip config for packages/release-tooling.
e2e/smoke/test/fixtures/cloudflare/wrangler.json Update compatibility date and D1 config fields.
e2e/smoke/test/fixtures/cloudflare/vitest.config.ts Remove workers-pool based vitest config.
e2e/smoke/test/fixtures/cloudflare/vitest.config.mts Add minimal vitest config stub.
e2e/smoke/test/fixtures/cloudflare/tsconfig.skip-lib-check-false.json Add tsconfig variant for lib-check coverage.
e2e/smoke/test/fixtures/cloudflare/tsconfig.json Remove explicit Cloudflare worker types from fixture tsconfig.
e2e/smoke/test/fixtures/cloudflare/test/migration.test.ts Add wrangler harness tests for repeated migrations.
e2e/smoke/test/fixtures/cloudflare/test/cold-start.test.ts Add Workers async-context concurrency regression test.
e2e/smoke/test/fixtures/cloudflare/test/env.d.ts Remove cloudflare:test env typing module.
e2e/smoke/test/fixtures/cloudflare/test/apply-migrations.ts Remove apply-migrations helper.
e2e/smoke/test/fixtures/cloudflare/src/db.ts Remove drizzle helper from fixture.
e2e/smoke/test/fixtures/cloudflare/src/auth.ts Add Better Auth setup using Workers env.DB.
e2e/smoke/test/fixtures/cloudflare/drizzle/meta/_journal.json Remove drizzle journal file from fixture.
e2e/smoke/test/fixtures/cloudflare/drizzle.config.ts Remove drizzle-kit config from fixture.
e2e/smoke/package.json Add @better-auth-test/test-utils workspace dependency.
e2e/integration/vanilla-node/e2e/postgres-js.spec.ts Make table-name assertion order-independent.
e2e/integration/package.json Prepare Nuxt fixture before running integration Playwright tests.
e2e/integration/nuxt/tsconfig.json Add Nuxt tsconfig references file.
e2e/integration/nuxt/test/nuxt/session-fetch.test-d.ts Add type contract checks for Nuxt useFetch compatibility.
e2e/integration/nuxt/server/api/auth/[...all].ts Add Nuxt server handler proxy to Better Auth handler.
e2e/integration/nuxt/package.json Add Nuxt fixture package with pinned Nuxt/test dependencies.
e2e/integration/nuxt/nuxt.config.ts Add minimal Nuxt config with devtools disabled.
e2e/integration/nuxt/lib/auth.ts Add Better Auth instance for Nuxt fixture.
e2e/integration/nuxt/lib/auth-client.ts Add Vue auth client for Nuxt fixture.
e2e/integration/nuxt/app/pages/index.vue Add page using authClient.useSession(useFetch).
e2e/integration/nuxt/app/app.vue Add Nuxt root app shell.
e2e/adapter/test/prisma-adapter/base.prisma Remove issuer and unique index from adapter fixture schema.
e2e/adapter/test/drizzle-adapter/adapter.drizzle.plural-joins.test.ts Remove issuer from schema and SQL assertions.
e2e/adapter/test/drizzle-adapter/adapter.drizzle.mixed-where.test.ts Remove issuer from schema and SQL assertions.
e2e/adapter/package.json Update mysql2 dev dependency version.
docs/vitest.config.ts Add alias resolution for docs tests.
docs/tsconfig.json Allow importing TS extensions in docs.
docs/source.config.ts Add shared page schema + processed markdown options; introduce generated v1.6 docs source.
docs/proxy.ts Add proxy rewrite for markdown negotiation under /docs/*.
docs/next.config.js Add redirects for renamed dashboard docs paths.
docs/lib/page-tree.test.ts Add tests for folder index path matching.
docs/lib/mobile-navigation.ts Add client-side navigation view store using useSyncExternalStore.
docs/lib/markdown-response.ts Add helpers for markdown responses with correct headers/vary.
docs/lib/docs-version-sources.ts Add version-to-source mapping for docs versions.
docs/content/docs/reference/telemetry.mdx Add icon frontmatter.
docs/content/docs/reference/resources.mdx Add icon frontmatter.
docs/content/docs/reference/options.mdx Document validateSchema option and add icon frontmatter.
docs/content/docs/reference/meta.json Add reference section meta with icon and ordering.
docs/content/docs/reference/instrumentation.mdx Add icon and sidebar title metadata.
docs/content/docs/reference/faq.mdx Add icon frontmatter.
docs/content/docs/reference/errors/meta.json Add errors section meta for reference errors pages.
docs/content/docs/reference/errors/index.mdx Add icon frontmatter.
docs/content/docs/reference/errors/account_already_linked_to_different_user.mdx Update wording to reflect (providerId, accountId) account keying.
docs/content/docs/reference/contributing.mdx Add icons and link to social-provider contribution policy.
docs/content/docs/plugins/username.mdx Add icon frontmatter.
docs/content/docs/plugins/test-utils.mdx Add icon frontmatter.
docs/content/docs/plugins/stripe.mdx Add icon frontmatter.
docs/content/docs/plugins/siwe.mdx Add icon + update email domain option docs.
docs/content/docs/plugins/scim/reference.mdx Add icon and sidebar title metadata.
docs/content/docs/plugins/scim/meta.json Add icon/pagesIndex and ordering.
docs/content/docs/plugins/scim/index.mdx Add icon and sidebar title metadata.
docs/content/docs/plugins/scim/groups-and-roles.mdx Add icon frontmatter.
docs/content/docs/plugins/polar.mdx Add icon frontmatter.
docs/content/docs/plugins/phone-number.mdx Add icon frontmatter.
docs/content/docs/plugins/passkey.mdx Add icon frontmatter.
docs/content/docs/plugins/organization.mdx Add icon frontmatter.
docs/content/docs/plugins/open-api.mdx Add icon frontmatter.
docs/content/docs/plugins/one-time-token.mdx Add icon and sidebar title metadata.
docs/content/docs/plugins/one-tap.mdx Add icon frontmatter.
docs/content/docs/plugins/oauth-proxy.mdx Add icon frontmatter.
docs/content/docs/plugins/oauth-provider.mdx Add icon and sidebar title metadata.
docs/content/docs/plugins/multi-session.mdx Add icon frontmatter.
docs/content/docs/plugins/mcp.mdx Add icon frontmatter.
docs/content/docs/plugins/magic-link.mdx Add icon and sidebar title metadata.
docs/content/docs/plugins/last-login-method.mdx Add icon frontmatter.
docs/content/docs/plugins/jwt.mdx Add icon frontmatter.
docs/content/docs/plugins/i18n.mdx Add icon frontmatter.
docs/content/docs/plugins/have-i-been-pwned.mdx Add icon + document custom password flow usage.
docs/content/docs/plugins/email-otp.mdx Add icon frontmatter.
docs/content/docs/plugins/dub.mdx Add icon frontmatter.
docs/content/docs/plugins/dodopayments.mdx Add icon frontmatter.
docs/content/docs/plugins/device-authorization.mdx Add icon frontmatter.
docs/content/docs/plugins/creem.mdx Add icon frontmatter.
docs/content/docs/plugins/community-plugins.mdx Add icon frontmatter.
docs/content/docs/plugins/commet.mdx Add icon frontmatter.
docs/content/docs/plugins/cimd.mdx Add icon and sidebar title metadata.
docs/content/docs/plugins/chargebee.mdx Add icon frontmatter.
docs/content/docs/plugins/captcha.mdx Add icon frontmatter.
docs/content/docs/plugins/bearer.mdx Add icon and sidebar title metadata.
docs/content/docs/plugins/autumn.mdx Add icon frontmatter.
docs/content/docs/plugins/api-key/reference.mdx Add icon frontmatter.
docs/content/docs/plugins/api-key/meta.json Add icon/pagesIndex and ordering.
docs/content/docs/plugins/api-key/index.mdx Add icon frontmatter.
docs/content/docs/plugins/api-key/advanced.mdx Add icon frontmatter.
docs/content/docs/plugins/agent-auth.mdx Add icon and “New” badge.
docs/content/docs/plugins/admin.mdx Add icon frontmatter.
docs/content/docs/plugins/2fa.mdx Add icon/sidebarTitle and document TOTP_ALREADY_ENABLED.
docs/content/docs/meta.json Restructure top-level docs navigation and add icons.
docs/content/docs/introduction.mdx Add icon frontmatter.
docs/content/docs/integrations/waku.mdx Add icon/sidebar title metadata.
docs/content/docs/integrations/tanstack.mdx Add icon/sidebar title metadata.
docs/content/docs/integrations/svelte-kit.mdx Add icon/sidebar title metadata.
docs/content/docs/integrations/solid-start.mdx Add icon/sidebar title metadata.
docs/content/docs/integrations/react-router.mdx Add icon/sidebar title metadata.
docs/content/docs/integrations/nuxt.mdx Add icon/sidebar title metadata.
docs/content/docs/integrations/next.mdx Add icon/sidebar title metadata.
docs/content/docs/integrations/nestjs.mdx Add icon/sidebar title metadata.
docs/content/docs/integrations/meta.json Add integrations section meta and ordering.
docs/content/docs/integrations/lynx.mdx Add icon/sidebar title metadata.
docs/content/docs/integrations/hono.mdx Add icon/sidebar title metadata and fix callout indentation.
docs/content/docs/integrations/fastify.mdx Add icon/sidebar title metadata.
docs/content/docs/integrations/express.mdx Clarify middleware ordering guidance; add icon/sidebar title.
docs/content/docs/integrations/expo.mdx Add icon/sidebar title and note storage write coordination.
docs/content/docs/integrations/encore.mdx Add icon/sidebar title metadata.
docs/content/docs/integrations/elysia.mdx Add icon/sidebar title metadata.
docs/content/docs/integrations/electron.mdx Add icon/sidebar title metadata.
docs/content/docs/integrations/convex.mdx Add icon/sidebar title metadata.
docs/content/docs/integrations/astro.mdx Add icon/sidebar title metadata.
docs/content/docs/infrastructure/services/sms.mdx Add icon/sidebar title metadata.
docs/content/docs/infrastructure/services/meta.json Add services section meta.
docs/content/docs/infrastructure/services/email.mdx Add icon/sidebar title metadata.
docs/content/docs/infrastructure/plugins/sentinel.mdx Add icon/sidebar title metadata.
docs/content/docs/infrastructure/plugins/meta.json Add plugins section meta.
docs/content/docs/infrastructure/plugins/audit-logs.mdx Add icon frontmatter.
docs/content/docs/infrastructure/meta.json Add infrastructure section meta and ordering.
docs/content/docs/infrastructure/introduction.mdx Add icon/sidebar title metadata.
docs/content/docs/infrastructure/getting-started.mdx Add icon frontmatter.
docs/content/docs/guides/your-first-plugin.mdx Add icon/sidebar title metadata.
docs/content/docs/guides/workos-migration-guide.mdx Add icon/sidebar title metadata.
docs/content/docs/guides/saml-sso-with-okta.mdx Add icon frontmatter.
docs/content/docs/guides/optimizing-for-performance.mdx Add icon/sidebar title metadata.
docs/content/docs/guides/meta.json Add guides section meta and ordering.
docs/content/docs/guides/dynamic-base-url.mdx Add icon frontmatter.
docs/content/docs/guides/browser-extension-guide.mdx Add icon frontmatter.
docs/content/docs/concepts/typescript.mdx Add icon frontmatter.
docs/content/docs/concepts/session-management.mdx Add icon/sidebar title and correct strategy comment list.
docs/content/docs/concepts/rate-limit.mdx Add icon frontmatter.
docs/content/docs/concepts/plugins.mdx Add icon frontmatter.
docs/content/docs/concepts/meta.json Add concepts section meta and ordering.
docs/content/docs/concepts/hooks.mdx Add icon frontmatter.
docs/content/docs/concepts/email.mdx Add icon frontmatter.
docs/content/docs/concepts/cookies.mdx Add icon frontmatter.
docs/content/docs/concepts/client.mdx Add icon frontmatter.
docs/content/docs/concepts/api.mdx Add icon frontmatter.
docs/content/docs/comparison.mdx Add icon frontmatter.
docs/content/docs/basic-usage.mdx Add icon frontmatter.
docs/content/docs/authentication/zoom.mdx Add icon frontmatter.
docs/content/docs/authentication/wechat.mdx Add icon frontmatter.
docs/content/docs/authentication/vk.mdx Add icon frontmatter.
docs/content/docs/authentication/vercel.mdx Add icon frontmatter.
docs/content/docs/authentication/twitter.mdx Add icon frontmatter.
docs/content/docs/authentication/twitch.mdx Add icon frontmatter.
docs/content/docs/authentication/tiktok.mdx Add icon and update placeholder email explanation.
docs/content/docs/authentication/spotify.mdx Add icon frontmatter.
docs/content/docs/authentication/slack.mdx Add icon frontmatter.
docs/content/docs/authentication/salesforce.mdx Add icon frontmatter.
docs/content/docs/authentication/roblox.mdx Add icon and update placeholder email explanation.
docs/content/docs/authentication/reddit.mdx Add icon frontmatter.
docs/content/docs/authentication/railway.mdx Add icon frontmatter.
docs/content/docs/authentication/polar.mdx Add icon frontmatter.
docs/content/docs/authentication/paypal.mdx Add icon frontmatter.
docs/content/docs/authentication/paybin.mdx Add icon frontmatter.
docs/content/docs/authentication/notion.mdx Add icon frontmatter.
docs/content/docs/authentication/naver.mdx Add icon frontmatter.
docs/content/docs/authentication/microsoft.mdx Add icon frontmatter.
docs/content/docs/authentication/meta.json Add authentication section meta and ordering.
docs/content/docs/authentication/linkedin.mdx Add icon frontmatter.
docs/content/docs/authentication/linear.mdx Add icon frontmatter.
docs/content/docs/authentication/line.mdx Add icon frontmatter.
docs/content/docs/authentication/kick.mdx Add icon frontmatter.
docs/content/docs/authentication/kakao.mdx Add icon frontmatter.
docs/content/docs/authentication/huggingface.mdx Add icon frontmatter.
docs/content/docs/authentication/google.mdx Add icon frontmatter.
docs/content/docs/authentication/gitlab.mdx Add icon frontmatter.
docs/content/docs/authentication/github.mdx Add icon frontmatter.
docs/content/docs/authentication/figma.mdx Add icon frontmatter.
docs/content/docs/authentication/facebook.mdx Add icon frontmatter.
docs/content/docs/authentication/email-password.mdx Add icon and update plugin link to /docs/plugins/2fa.
docs/content/docs/authentication/dropbox.mdx Add icon frontmatter.
docs/content/docs/authentication/discord.mdx Add icon frontmatter.
docs/content/docs/authentication/cognito.mdx Add icon frontmatter.
docs/content/docs/authentication/atlassian.mdx Add icon frontmatter.
docs/content/docs/authentication/apple.mdx Add icon frontmatter.
docs/content/docs/ai-resources/skills.mdx Add icon frontmatter.
docs/content/docs/ai-resources/meta.json Add icon/pagesIndex and LLMs link entry.
docs/content/docs/adapters/sqlite.mdx Add icon frontmatter.
docs/content/docs/adapters/postgresql.mdx Add icon frontmatter.
docs/content/docs/adapters/other-relational-databases.mdx Add icon frontmatter.
docs/content/docs/adapters/mysql.mdx Add icon frontmatter.
docs/content/docs/adapters/mssql.mdx Add icon frontmatter.
docs/content/docs/adapters/mongo.mdx Add icon/sidebar title metadata.
docs/content/docs/adapters/meta.json Add databases section meta and ordering.
docs/content/docs/adapters/drizzle.mdx Add icon/sidebar title metadata.
docs/content/docs/adapters/community-adapters.mdx Add icon frontmatter.
docs/content/blogs/1-7-rc.mdx Remove issuer migration guidance entries now that issuer is removed.
docs/content/_generated/docs/v1-6/.gitkeep Add generated docs placeholder for v1.6 source.
docs/components/search-dialog.tsx Tag Typesense queries by docs version based on pathname.
docs/components/endpoint.tsx Use shared API method type and add PATCH color mapping.
docs/app/docs/shell.tsx Add simplified docs layout shell without nav/search/sidebar toggles.
docs/app/docs/llms.txt/route.ts Add static route serving LLMs index with canonical link header.
docs/app/blog/layout.tsx Disable theme switch in blog root provider.
docs/.gitignore Update ignored generated docs sync targets.
demo/nextjs/package.json Update mysql2 and bump zod version for demo app dependencies.
.github/workflows/verify-changesets.yml Update branch patterns and exclude release-tooling from changeset enforcement.
.github/workflows/preview.yml Switch to shared setup action and use pnpm exec pkg-pr-new.
.github/workflows/lint-github-actions.yml Add workflow to lint GitHub Actions via shared workflow.
.github/workflows/demo.yml Switch demo workflow to shared pnpm setup action.
.github/scripts/lib/github.ts Remove now-obsolete shared GitHub helper script.
.cspell/tech-terms.txt Add additional technical dictionary entries.
.cspell/names.txt Add contributor name entry.
.cspell/custom-words.txt Add custom words used in repo.
.cspell/company-names.txt Add company/product term entry.
.changeset/new-brooms-prove.md Add changeset for email validation error-code behavior.
Review details
  • Files reviewed: 293/640 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 17 to 22
const signUpEmailBodySchema = z
.object({
name: z.string(),
email: z.email(),
email: z.string().nonempty(),
password: z.string().nonempty(),
image: z.string().optional(),
Comment on lines 10 to 13
export const accountSchema = coreSchema.extend({
providerId: z.string(),
issuer: z.string(),
accountId: z.string(),
userId: z.coerce.string(),
Comment thread .changeset/new-brooms-prove.md Outdated
"better-auth": minor
---

Loosens email validation on sign-up and update-user endpoints. This changes the behavior of the endpoint in case the email is invalid that it throws now INVALID_EMAIL instead of VALIDATION_ERROR which grants developers the capability to show the users a more granular and translateable error. The endpoint now returns one error after the other instead of an array with all errors and error messages in english.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found and verified against the latest diff

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/better-auth/src/api/routes/update-user.ts">

<violation number="1" location="packages/better-auth/src/api/routes/update-user.ts:731">
P3: The new INVALID_EMAIL path on change-email has no test coverage. Add a case that sends an ill-formed newEmail and asserts the response code is INVALID_EMAIL (and that a missing newEmail still returns VALIDATION_ERROR), so the intended error-code contract is locked in.</violation>
</file>

<file name="packages/better-auth/src/api/routes/sign-up.ts">

<violation number="1" location="packages/better-auth/src/api/routes/sign-up.ts:20">
P3: An empty-string email (`email: ""`) is rejected by `.nonempty()` at the schema layer, so it returns the generic VALIDATION_ERROR instead of the new INVALID_EMAIL. That leaves an ill-formed email indistinguishable from the missing-field case the PR wants clients to tell apart. Drop `.nonempty()` (`email: z.string()`) so empty strings reach the handler's `z.email().safeParse` check; a missing field is still rejected by `z.string()`.</violation>

<violation number="2" location="packages/better-auth/src/api/routes/sign-up.ts:20">
P2: Add a regression test that submits an ill-formed email and asserts the endpoint returns `INVALID_EMAIL` instead of `VALIDATION_ERROR`.</violation>
</file>

Note: This PR contains a large number of files. cubic selects up to 200 of the highest-priority eligible files for this review, so some files may not have been reviewed.

Fix all with cubic | Re-trigger cubic

@@ -18,7 +17,7 @@ import { createEmailVerificationToken } from "./email-verification";
const signUpEmailBodySchema = z
.object({
name: z.string(),
email: z.email(),
email: z.string().nonempty(),

@cubic-dev-ai cubic-dev-ai Bot Sep 7, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Add a regression test that submits an ill-formed email and asserts the endpoint returns INVALID_EMAIL instead of VALIDATION_ERROR.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/better-auth/src/api/routes/sign-up.ts, line 20:

<comment>Add a regression test that submits an ill-formed email and asserts the endpoint returns `INVALID_EMAIL` instead of `VALIDATION_ERROR`.</comment>

<file context>
@@ -17,7 +17,7 @@ import { createEmailVerificationToken } from "./email-verification";
 	.object({
 		name: z.string(),
-		email: z.email(),
+		email: z.string().nonempty(),
 		password: z.string().nonempty(),
 		image: z.string().optional(),
</file context>
Fix with cubic

const isValidEmail = z.email().safeParse(ctx.body.newEmail);

if (!isValidEmail.success) {
throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.INVALID_EMAIL);

@cubic-dev-ai cubic-dev-ai Bot Sep 7, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The new INVALID_EMAIL path on change-email has no test coverage. Add a case that sends an ill-formed newEmail and asserts the response code is INVALID_EMAIL (and that a missing newEmail still returns VALIDATION_ERROR), so the intended error-code contract is locked in.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/better-auth/src/api/routes/update-user.ts, line 731:

<comment>The new INVALID_EMAIL path on change-email has no test coverage. Add a case that sends an ill-formed newEmail and asserts the response code is INVALID_EMAIL (and that a missing newEmail still returns VALIDATION_ERROR), so the intended error-code contract is locked in.</comment>

<file context>
@@ -725,6 +725,11 @@ export const changeEmail = createAuthEndpoint(
+		const isValidEmail = z.email().safeParse(ctx.body.newEmail);
+
+		if (!isValidEmail.success) {
+			throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.INVALID_EMAIL);
+		}
 
</file context>
Fix with cubic

@@ -18,7 +17,7 @@ import { createEmailVerificationToken } from "./email-verification";
const signUpEmailBodySchema = z
.object({
name: z.string(),
email: z.email(),
email: z.string().nonempty(),

@cubic-dev-ai cubic-dev-ai Bot Sep 7, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: An empty-string email (email: "") is rejected by .nonempty() at the schema layer, so it returns the generic VALIDATION_ERROR instead of the new INVALID_EMAIL. That leaves an ill-formed email indistinguishable from the missing-field case the PR wants clients to tell apart. Drop .nonempty() (email: z.string()) so empty strings reach the handler's z.email().safeParse check; a missing field is still rejected by z.string().

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/better-auth/src/api/routes/sign-up.ts, line 20:

<comment>An empty-string email (`email: ""`) is rejected by `.nonempty()` at the schema layer, so it returns the generic VALIDATION_ERROR instead of the new INVALID_EMAIL. That leaves an ill-formed email indistinguishable from the missing-field case the PR wants clients to tell apart. Drop `.nonempty()` (`email: z.string()`) so empty strings reach the handler's `z.email().safeParse` check; a missing field is still rejected by `z.string()`.</comment>

<file context>
@@ -17,7 +17,7 @@ import { createEmailVerificationToken } from "./email-verification";
 	.object({
 		name: z.string(),
-		email: z.email(),
+		email: z.string().nonempty(),
 		password: z.string().nonempty(),
 		image: z.string().optional(),
</file context>
Fix with cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Core infra, API routes, session, cookies, client SDK

Projects

None yet

Development

Successfully merging this pull request may close these issues.