[GH-ISSUE #8122] phone-number plugin: OpenAPI spec missing requestBody for /phone-number/verify in v1.4.19 #28325

Open
opened 2026-04-17 19:44:57 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @shreyfirst on GitHub (Feb 24, 2026).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/8122

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Configure better-auth with the phoneNumber and openAPI plugins
  2. Call auth.api.generateOpenAPISchema()
  3. Inspect spec.paths["/phone-number/verify"].post

In v1.4.18, the endpoint includes a requestBody with phoneNumber, code, disableSession, and updatePhoneNumber fields.

In v1.4.19, the requestBody is completely missing from the generated schema.

import { betterAuth } from "better-auth";
import { phoneNumber, openAPI } from "better-auth/plugins";

const auth = betterAuth({
  plugins: [
    phoneNumber({
      sendOTP({ phoneNumber, code }) { /* ... */ },
      signUpOnVerification: {
        getTempEmail: (phone) => `${phone}@phone.example.com`,
      },
    }),
    openAPI(),
  ],
});

const spec = await auth.api.generateOpenAPISchema();
const verify = spec.paths["/phone-number/verify"]?.post;
console.log("requestBody" in verify); // v1.4.18: true, v1.4.19: false

Current vs. Expected behavior

Current (v1.4.19): /phone-number/verify POST endpoint has no requestBody in the OpenAPI spec. Generated clients (e.g. swift-openapi-generator) produce a function with no body parameter, making it impossible to send the phone number and OTP code.

Expected: The endpoint should include the requestBody with phoneNumber (required) and code (required) fields, as it did in v1.4.18.

What version of Better Auth are you using?

1.4.19 (regression from 1.4.18)

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

Plugin, OpenAPI

Additional context

This was likely introduced by the phone-number plugin change "Support user additionalFields in signUpOnVerification flow" in v1.4.19. The verify endpoint still works correctly at runtime (accepts the body and verifies OTPs), but the OpenAPI schema no longer documents the request body.

Workaround: pin to v1.4.18.

Originally created by @shreyfirst on GitHub (Feb 24, 2026). Original GitHub issue: https://github.com/better-auth/better-auth/issues/8122 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Configure better-auth with the `phoneNumber` and `openAPI` plugins 2. Call `auth.api.generateOpenAPISchema()` 3. Inspect `spec.paths["/phone-number/verify"].post` In v1.4.18, the endpoint includes a `requestBody` with `phoneNumber`, `code`, `disableSession`, and `updatePhoneNumber` fields. In v1.4.19, the `requestBody` is completely missing from the generated schema. ```typescript import { betterAuth } from "better-auth"; import { phoneNumber, openAPI } from "better-auth/plugins"; const auth = betterAuth({ plugins: [ phoneNumber({ sendOTP({ phoneNumber, code }) { /* ... */ }, signUpOnVerification: { getTempEmail: (phone) => `${phone}@phone.example.com`, }, }), openAPI(), ], }); const spec = await auth.api.generateOpenAPISchema(); const verify = spec.paths["/phone-number/verify"]?.post; console.log("requestBody" in verify); // v1.4.18: true, v1.4.19: false ``` ### Current vs. Expected behavior **Current (v1.4.19):** `/phone-number/verify` POST endpoint has no `requestBody` in the OpenAPI spec. Generated clients (e.g. swift-openapi-generator) produce a function with no body parameter, making it impossible to send the phone number and OTP code. **Expected:** The endpoint should include the `requestBody` with `phoneNumber` (required) and `code` (required) fields, as it did in v1.4.18. ### What version of Better Auth are you using? 1.4.19 (regression from 1.4.18) ### Which area(s) are affected? (Select all that apply) Plugin, OpenAPI ### Additional context This was likely introduced by the phone-number plugin change "Support user additionalFields in signUpOnVerification flow" in v1.4.19. The verify endpoint still works correctly at runtime (accepts the body and verifies OTPs), but the OpenAPI schema no longer documents the request body. Workaround: pin to v1.4.18.
GiteaMirror added the devtoolscredentialsbug labels 2026-04-17 19:44:57 -05:00
Author
Owner

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

Hi @shreyfirst! I'm Dosu and I’m helping the better-auth team.

You've correctly identified the root cause. PR #7699 modified the /phone-number/verify endpoint's body schema to support additionalFields during the signUpOnVerification flow by adding .and(z.record(z.string(), z.any())):

const verifyPhoneNumberBodySchema = z
  .object({
    phoneNumber: z.string(),
    code: z.string(),
    disableSession: z.boolean().optional(),
    updatePhoneNumber: z.boolean().optional(),
  })
  .and(z.record(z.string(), z.any()));

The OpenAPI generator's processZodType function has no handler for ZodIntersection types (created by .and()), so it falls back to returning { type: "string" } instead of properly merging the schemas.

This same pattern is used in other endpoints like /sign-up, so those may also have incomplete OpenAPI schemas.

A proper fix would require adding ZodIntersection (and potentially z.record()) support to the OpenAPI generator.

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:3948950195 --> @dosubot[bot] commented on GitHub (Feb 24, 2026): <!-- Greeting --> Hi @shreyfirst! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> You've correctly identified the root cause. [PR #7699](https://github.com/better-auth/better-auth/pull/7699) modified the `/phone-number/verify` endpoint's body schema to support `additionalFields` during the `signUpOnVerification` flow by [adding `.and(z.record(z.string(), z.any()))`](https://github.com/better-auth/better-auth/blob/1892ca3b0081afeaa4e3fb5c5e389a821f7fd863/packages/better-auth/src/plugins/phone-number/routes.ts#L325): ```typescript const verifyPhoneNumberBodySchema = z .object({ phoneNumber: z.string(), code: z.string(), disableSession: z.boolean().optional(), updatePhoneNumber: z.boolean().optional(), }) .and(z.record(z.string(), z.any())); ``` The [OpenAPI generator's `processZodType` function](https://github.com/better-auth/better-auth/blob/1892ca3b0081afeaa4e3fb5c5e389a821f7fd863/packages/better-auth/src/plugins/open-api/generator.ts#L196) has **no handler for `ZodIntersection` types** (created by `.and()`), so it falls back to returning `{ type: "string" }` instead of properly merging the schemas. This same pattern is used in other endpoints like [`/sign-up`](https://github.com/better-auth/better-auth/blob/1892ca3b0081afeaa4e3fb5c5e389a821f7fd863/packages/better-auth/src/api/routes/sign-up.ts#L25), so those may also have incomplete OpenAPI schemas. A proper fix would require adding `ZodIntersection` (and potentially `z.record()`) support to the OpenAPI generator. <!-- 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/cdde4d58-675a-4143-8466-917cabb04f79?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/cdde4d58-675a-4143-8466-917cabb04f79?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/cdde4d58-675a-4143-8466-917cabb04f79?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/cdde4d58-675a-4143-8466-917cabb04f79?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/cdde4d58-675a-4143-8466-917cabb04f79?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/cdde4d58-675a-4143-8466-917cabb04f79?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/cdde4d58-675a-4143-8466-917cabb04f79?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%20correctly%20identified%20the%20root%20cause.%20%5BPR%20%237699%5D%28https%3A//github.com/better-auth/better-auth/pull/7699%29%20modified%20the%20%60/phone-number/verify%60%20endpoint%27s%20body%20schema%20to%20support%20%60additionalFields%60%20during%20the%20%60signUpOnVerification%60%20flow%20by%20%5Badding%20%60.and%28z.record%28z.string%28%29%2C%20z.any%28%29%29%29%60%5D%28https%3A//github.com/better-auth/better-auth/blob/1892ca3b0081afeaa4e3fb5c5e389a821f7fd863/packages/better-auth/src/plugins/phone-number/routes.ts%23L325%29%3A%0A%0A%60%60%60typescript%0Aconst%20verifyPhoneNumberBodySchema%20%3D%20z%0A%20%20.object%28%7B%0A%20%20%20%20phoneNumber%3A%20z.string%28%29%2C%0A%20%20%20%20code%3A%20z.string%28%29%2C%0A%20%20%20%20disableSession%3A%20z.boolean%28%29.optional%28%29%2C%0A%20%20%20%20updatePhoneNumber%3A%20z.boolean%28%29.optional%28%29%2C%0A%20%20%7D%29%0A%20%20.and%28z.record%28z.string%28%29%2C%20z.any%28%29%29%29%3B%0A%60%60%60%0A%0AThe%20%5BOpenAPI%20generator%27s%20%60processZodType%60%20function%5D%28https%3A//github.com/better-auth/better-auth/blob/1892ca3b0081afeaa4e3fb5c5e389a821f7fd863/packages/better-auth/src/plugins/open-api/generator.ts%23L196%29%20has%20%2A%2Ano%20handler%20for%20%60ZodIntersection%60%20types%2A%2A%20%28created%20by%20%60.and%28%29%60%29%2C%20so%20it%20falls%20back%20to%20returning%20%60%7B%20type%3A%20%22string%22%20%7D%60%20instead%20of%20properly%20merging%20the%20schemas.%0A%0AThis%20same%20pattern%20is%20used%20in%20other%20endpoints%20like%20%5B%60/sign-up%60%5D%28https%3A//github.com/better-auth/better-auth/blob/1892ca3b0081afeaa4e3fb5c5e389a821f7fd863/packages/better-auth/src/api/routes/sign-up.ts%23L25%29%2C%20so%20those%20may%20also%20have%20incomplete%20OpenAPI%20schemas.%0A%0AA%20proper%20fix%20would%20require%20adding%20%60ZodIntersection%60%20%28and%20potentially%20%60z.record%28%29%60%29%20support%20to%20the%20OpenAPI%20generator.)&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/8122)
Author
Owner

@gustavovalverde commented on GitHub (Apr 14, 2026):

Related in the same area (not duplicates): #8014, #1493.

<!-- gh-comment-id:4244779197 --> @gustavovalverde commented on GitHub (Apr 14, 2026): Related in the same area (not duplicates): #8014, #1493.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#28325