Skip to content

chore: use zod v3 syntax#4851

Merged
himself65 merged 1 commit intobetter-auth:canaryfrom
himself65:himself65/2025/09/23/zod
Sep 23, 2025
Merged

chore: use zod v3 syntax#4851
himself65 merged 1 commit intobetter-auth:canaryfrom
himself65:himself65/2025/09/23/zod

Conversation

@himself65
Copy link
Copy Markdown
Contributor

@himself65 himself65 commented Sep 23, 2025

Document: https://zod.dev/metadata?id=describe
Fixes: #4837


Summary by cubic

Migrated all endpoint and plugin schemas to Zod v3 syntax to standardize descriptions and improve consistency. No runtime behavior changes; API inputs and outputs remain the same.

  • Refactors

    • Replaced z.meta(...) with z.describe(...) across auth routes and plugins (sessions, sign-in, account, org, API keys, 2FA, passkey, phone, magic link, SSO/OIDC, etc.).
    • Standardized schema patterns (e.g., z.coerce for ids/booleans, defaults and optionals) while preserving existing validations and OpenAPI descriptions.
  • Migration

    • If you have custom schemas using z.meta, update them to .describe.
    • No action needed for consumers unless extending schemas; endpoint contracts are unchanged.

@himself65 himself65 requested a review from Bekacru as a code owner September 23, 2025 20:22
@vercel
Copy link
Copy Markdown

vercel bot commented Sep 23, 2025

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

A member of the Team first needs to authorize it.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Sep 23, 2025

Open in StackBlitz

better-auth

npm i https://pkg.pr.new/better-auth/better-auth@4851

@better-auth/cli

npm i https://pkg.pr.new/better-auth/better-auth/@better-auth/cli@4851

@better-auth/expo

npm i https://pkg.pr.new/better-auth/better-auth/@better-auth/expo@4851

@better-auth/sso

npm i https://pkg.pr.new/better-auth/better-auth/@better-auth/sso@4851

@better-auth/stripe

npm i https://pkg.pr.new/better-auth/better-auth/@better-auth/stripe@4851

commit: 24fc68c

@himself65 himself65 enabled auto-merge September 23, 2025 20:27
@himself65 himself65 added this pull request to the merge queue Sep 23, 2025
Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

13 issues found across 37 files

Prompt for AI agents (all 13 issues)

Understand the root cause of the following 13 issues and fix them.


<file name="packages/better-auth/src/plugins/organization/routes/crud-invites.ts">

<violation number="1" location="packages/better-auth/src/plugins/organization/routes/crud-invites.ts:847">
Rule violated: **Enforce Consistent Naming Conventions**

Use a descriptive parameter name for consistency and clarity; replace generic id with invitationId to align with other endpoints and naming conventions.</violation>
</file>

<file name="packages/better-auth/src/plugins/organization/routes/crud-access-control.ts">

<violation number="1" location="packages/better-auth/src/plugins/organization/routes/crud-access-control.ts:75">
Description text truncated mid-sentence; restore full message for clarity.</violation>

<violation number="2" location="packages/better-auth/src/plugins/organization/routes/crud-access-control.ts:606">
Description text truncated mid-sentence; restore full message for clarity.</violation>

<violation number="3" location="packages/better-auth/src/plugins/organization/routes/crud-access-control.ts:764">
Description text truncated mid-sentence; restore full message for clarity.</violation>
</file>

<file name="packages/better-auth/src/plugins/generic-oauth/index.ts">

<violation number="1" location="packages/better-auth/src/plugins/generic-oauth/index.ts:358">
Incomplete description string: the example is missing after &quot;Eg:&quot;. Provide a concrete example or remove the placeholder.</violation>
</file>

<file name="packages/better-auth/src/plugins/organization/routes/crud-members.ts">

<violation number="1" location="packages/better-auth/src/plugins/organization/routes/crud-members.ts:410">
Incomplete description string; trailing &#39;Eg: [&#39; indicates a truncated example. Clean up or complete the text.</violation>
</file>

<file name="packages/better-auth/src/plugins/organization/routes/crud-team.ts">

<violation number="1" location="packages/better-auth/src/plugins/organization/routes/crud-team.ts:563">
Typo in example: &quot;organziation-id&quot; should be &quot;organization-id&quot;.</violation>
</file>

<file name="packages/better-auth/src/plugins/one-time-token/index.ts">

<violation number="1" location="packages/better-auth/src/plugins/one-time-token/index.ts:132">
Zod describe string is incomplete (ends with &quot;Eg:&quot;), reducing clarity for docs; include an example or remove the &quot;Eg:&quot;.</violation>
</file>

<file name="packages/sso/src/index.ts">

<violation number="1" location="packages/sso/src/index.ts:342">
Truncated .describe() texts in oidcConfig.mapping (dangling &#39;(&#39; and missing defaults) degrade API docs clarity.</violation>
</file>

<file name="packages/better-auth/src/plugins/device-authorization/index.ts">

<violation number="1" location="packages/better-auth/src/plugins/device-authorization/index.ts:625">
Error enum for /device missing &quot;expired_token&quot;, which this endpoint returns when the user code is expired.</violation>
</file>

<file name="packages/better-auth/src/plugins/two-factor/otp/index.ts">

<violation number="1" location="packages/better-auth/src/plugins/two-factor/otp/index.ts:137">
Incomplete description string; it ends mid-sentence. Restore the full sentence and example for clarity in generated docs.</violation>
</file>

<file name="packages/better-auth/src/plugins/admin/admin.ts">

<violation number="1" location="packages/better-auth/src/plugins/admin/admin.ts:501">
Invalid Zod record key schema: use a string-like key (e.g., z.string()) instead of z.any() for z.record().</violation>

<violation number="2" location="packages/better-auth/src/plugins/admin/admin.ts:606">
Attach description to the union schema instead of a single branch to document the full (string | number | boolean) type.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

id: z.string().meta({
description: "The ID of the invitation to get",
}),
id: z.string().describe("The ID of the invitation to get"),
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Sep 23, 2025

Choose a reason for hiding this comment

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

Rule violated: Enforce Consistent Naming Conventions

Use a descriptive parameter name for consistency and clarity; replace generic id with invitationId to align with other endpoints and naming conventions.

Prompt for AI agents
Address the following comment on packages/better-auth/src/plugins/organization/routes/crud-invites.ts at line 847:

<comment>Use a descriptive parameter name for consistency and clarity; replace generic id with invitationId to align with other endpoints and naming conventions.</comment>

<file context>
@@ -869,9 +844,7 @@ export const getInvitation = &lt;O extends OrganizationOptions&gt;(options: O) =&gt;
-				id: z.string().meta({
-					description: &quot;The ID of the invitation to get&quot;,
-				}),
+				id: z.string().describe(&quot;The ID of the invitation to get&quot;),
 			}),
 			metadata: {
</file context>
Fix with Cubic

.string()
.optional()
.describe(
"The id of the organization to create the role in. If not provided, the user",
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Sep 23, 2025

Choose a reason for hiding this comment

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

Description text truncated mid-sentence; restore full message for clarity.

Prompt for AI agents
Address the following comment on packages/better-auth/src/plugins/organization/routes/crud-access-control.ts at line 75:

<comment>Description text truncated mid-sentence; restore full message for clarity.</comment>

<file context>
@@ -68,16 +68,16 @@ export const createOrgRole = &lt;O extends OrganizationOptions&gt;(options: O) =&gt; {
+					.string()
+					.optional()
+					.describe(
+						&quot;The id of the organization to create the role in. If not provided, the user&quot;,
+					),
+				role: z.string().describe(&quot;The name of the role to create&quot;),
</file context>
Fix with Cubic

.string()
.optional()
.describe(
"The id of the organization to read a role for. If not provided, the user",
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Sep 23, 2025

Choose a reason for hiding this comment

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

Description text truncated mid-sentence; restore full message for clarity.

Prompt for AI agents
Address the following comment on packages/better-auth/src/plugins/organization/routes/crud-access-control.ts at line 606:

<comment>Description text truncated mid-sentence; restore full message for clarity.</comment>

<file context>
@@ -599,22 +599,20 @@ export const getOrgRole = &lt;O extends OrganizationOptions&gt;(options: O) =&gt; {
+						.string()
+						.optional()
+						.describe(
+							&quot;The id of the organization to read a role for. If not provided, the user&quot;,
+						),
 				})
</file context>
Fix with Cubic

.string()
.optional()
.describe(
"The id of the organization to update the role in. If not provided, the user",
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Sep 23, 2025

Choose a reason for hiding this comment

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

Description text truncated mid-sentence; restore full message for clarity.

Prompt for AI agents
Address the following comment on packages/better-auth/src/plugins/organization/routes/crud-access-control.ts at line 764:

<comment>Description text truncated mid-sentence; restore full message for clarity.</comment>

<file context>
@@ -759,34 +757,31 @@ export const updateOrgRole = &lt;O extends OrganizationOptions&gt;(options: O) =&gt; {
+						.string()
+						.optional()
+						.describe(
+							&quot;The id of the organization to update the role in. If not provided, the user&quot;,
+						),
 					data: z.object({
</file context>
Fix with Cubic

'The URL to redirect to after login if the user is new. Eg: "/welcome"',
})
.describe(
"The URL to redirect to after login if the user is new. Eg: ",
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Sep 23, 2025

Choose a reason for hiding this comment

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

Incomplete description string: the example is missing after "Eg:". Provide a concrete example or remove the placeholder.

Prompt for AI agents
Address the following comment on packages/better-auth/src/plugins/generic-oauth/index.ts at line 358:

<comment>Incomplete description string: the example is missing after &quot;Eg:&quot;. Provide a concrete example or remove the placeholder.</comment>

<file context>
@@ -341,47 +341,38 @@ export const genericOAuth = (options: GenericOAuthOptions) =&gt; {
-									&#39;The URL to redirect to after login if the user is new. Eg: &quot;/welcome&quot;&#39;,
-							})
+							.describe(
+								&quot;The URL to redirect to after login if the user is new. Eg: &quot;,
+							)
 							.optional(),
</file context>
Suggested change
"The URL to redirect to after login if the user is new. Eg: ",
"The URL to redirect to after login if the user is new. Eg: \"/welcome\"",
Fix with Cubic

description:
"Field mapping for image (defaults to 'picture')",
})
.describe("Field mapping for image (")
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Sep 23, 2025

Choose a reason for hiding this comment

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

Truncated .describe() texts in oidcConfig.mapping (dangling '(' and missing defaults) degrade API docs clarity.

Prompt for AI agents
Address the following comment on packages/sso/src/index.ts at line 342:

<comment>Truncated .describe() texts in oidcConfig.mapping (dangling &#39;(&#39; and missing defaults) degrade API docs clarity.</comment>

<file context>
@@ -284,95 +284,62 @@ export const sso = (options?: SSOOptions) =&gt; {
-												description:
-													&quot;Field mapping for image (defaults to &#39;picture&#39;)&quot;,
-											})
+											.describe(&quot;Field mapping for image (&quot;)
 											.optional(),
 										extraFields: z.record(z.string(), z.any()).optional(),
</file context>
Fix with Cubic

error_description: z.string().meta({
description: "Detailed error description",
}),
error: z.enum(["invalid_request"]).describe("Error code"),
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Sep 23, 2025

Choose a reason for hiding this comment

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

Error enum for /device missing "expired_token", which this endpoint returns when the user code is expired.

Prompt for AI agents
Address the following comment on packages/better-auth/src/plugins/device-authorization/index.ts at line 625:

<comment>Error enum for /device missing &quot;expired_token&quot;, which this endpoint returns when the user code is expired.</comment>

<file context>
@@ -631,17 +619,13 @@ Follow [rfc8628#section-3.4](https://datatracker.ietf.org/doc/html/rfc8628#secti
-						error_description: z.string().meta({
-							description: &quot;Detailed error description&quot;,
-						}),
+						error: z.enum([&quot;invalid_request&quot;]).describe(&quot;Error code&quot;),
+						error_description: z
+							.string()
</file context>
Suggested change
error: z.enum(["invalid_request"]).describe("Error code"),
error: z.enum(["invalid_request", "expired_token"]).describe("Error code"),
Fix with Cubic

trustDevice: z
.boolean()
.optional()
.describe("If true, the device will be trusted for 30 days. It"),
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Sep 23, 2025

Choose a reason for hiding this comment

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

Incomplete description string; it ends mid-sentence. Restore the full sentence and example for clarity in generated docs.

Prompt for AI agents
Address the following comment on packages/better-auth/src/plugins/two-factor/otp/index.ts at line 137:

<comment>Incomplete description string; it ends mid-sentence. Restore the full sentence and example for clarity in generated docs.</comment>

<file context>
@@ -131,10 +131,10 @@ export const otp2fa = (options?: OTPOptions) =&gt; {
+					trustDevice: z
+						.boolean()
+						.optional()
+						.describe(&quot;If true, the device will be trusted for 30 days. It&quot;),
 				})
 				.optional(),
</file context>
Fix with Cubic

.meta({
description: "The value to filter by",
})
.describe("The value to filter by")
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Sep 23, 2025

Choose a reason for hiding this comment

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

Attach description to the union schema instead of a single branch to document the full (string | number | boolean) type.

Prompt for AI agents
Address the following comment on packages/better-auth/src/plugins/admin/admin.ts at line 606:

<comment>Attach description to the union schema instead of a single branch to document the full (string | number | boolean) type.</comment>

<file context>
@@ -584,68 +566,50 @@ export const admin = &lt;O extends AdminOptions&gt;(options?: O) =&gt; {
-							.meta({
-								description: &quot;The value to filter by&quot;,
-							})
+							.describe(&quot;The value to filter by&quot;)
 							.or(z.number())
 							.or(z.boolean())
</file context>
Fix with Cubic

}),
userId: z.coerce.string().describe("The user id"),
data: z
.record(z.any(), z.any())
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Sep 23, 2025

Choose a reason for hiding this comment

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

Invalid Zod record key schema: use a string-like key (e.g., z.string()) instead of z.any() for z.record().

Prompt for AI agents
Address the following comment on packages/better-auth/src/plugins/admin/admin.ts at line 501:

<comment>Invalid Zod record key schema: use a string-like key (e.g., z.string()) instead of z.any() for z.record().</comment>

<file context>
@@ -512,12 +496,10 @@ export const admin = &lt;O extends AdminOptions&gt;(options?: O) =&gt; {
-						}),
+						userId: z.coerce.string().describe(&quot;The user id&quot;),
+						data: z
+							.record(z.any(), z.any())
+							.describe(&quot;The user data to update&quot;),
 					}),
</file context>
Suggested change
.record(z.any(), z.any())
.record(z.string(), z.any())
Fix with Cubic

Merged via the queue into better-auth:canary with commit 7fa0c2d Sep 23, 2025
8 of 10 checks passed
himself65 added a commit to himself65/better-auth that referenced this pull request Sep 23, 2025
himself65 added a commit that referenced this pull request Sep 23, 2025
himself65 added a commit to himself65/better-auth that referenced this pull request Sep 25, 2025
himself65 added a commit that referenced this pull request Sep 25, 2025
himself65 added a commit that referenced this pull request Sep 25, 2025
himself65 added a commit that referenced this pull request Sep 25, 2025
himself65 added a commit that referenced this pull request Sep 25, 2025
rae-fcm pushed a commit to FullCodeMedical/better-auth that referenced this pull request Mar 9, 2026
rae-fcm pushed a commit to FullCodeMedical/better-auth that referenced this pull request Mar 9, 2026
@better-auth better-auth locked as resolved and limited conversation to collaborators Apr 1, 2026
@bytaesu bytaesu added the locked Locked conversations after being closed for 7 days label Apr 1, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

locked Locked conversations after being closed for 7 days

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1.3.10 and later does not work on zod 3 projects

2 participants