docs(x402): document error_detail.payment_rejected on the 402 challenge body - #45
docs(x402): document error_detail.payment_rejected on the 402 challenge body#45yakimoto wants to merge 3 commits into
Conversation
…ge body Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_72689e86-3d94-46c1-9491-fc1621a71f31) |
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 1 minute Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Comment |
PR Summary by QodoDocument X402 402 challenge payment_rejected deny verdict in OpenAPI
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
There was a problem hiding this comment.
Risk: low. Left a non-blocking comment — Cursor Bugbot and Cursor Security Agent both skipped (Bugbot reported a usage limit), so required automated review signals did not complete successfully and human review is needed. No reviewers were assigned because no eligible non-author reviewers could be identified from available ownership/history.
Sent by Cursor Approval Agent: Pull Request Router and Approver
ApprovabilityVerdict: Approved b51c42e Documentation-only changes to OpenAPI spec file documenting existing gateway behavior. Author owns both modified files. The open review comment requests verification that documented nesting matches actual wire shape - a documentation accuracy concern, not a runtime safety issue. You can customize Macroscope's approvability policy. Learn more. |
…uard Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
Code Review by Qodo
1. openapi.yaml exceeds 500 lines
|
Qodo FixerNo findings are within the configured fix scope. To change which findings are fixed, adjust the setting on your Qodo configuration page. |
… envelope Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
| error_detail: | ||
| $ref: '#/components/schemas/Error' | ||
| allOf: | ||
| - $ref: '#/components/schemas/ErrorBody' | ||
| - type: object |
There was a problem hiding this comment.
🔍 Refactor changes the generated type for error_detail (breaking for existing consumers)
The extraction of ErrorBody leaves every other response byte-identical (the Error envelope now just $refs the extracted object), but error_detail itself changes shape: it used to generate as { error: { code, message, ... } } and now generates as { code, message, ..., payment_rejected? }. Consumers that already generated types from the previous spec and read error_detail.error.code will break at their next regeneration. The CHANGELOG records this under "Fixed" (CHANGELOG.md:9-16), which is reasonable if the old spec was wrong on the wire, but the claim that the gateway nests the bare error object is unverifiable from this repo — worth confirming against an actual 402 body before release, since it is effectively a breaking change for SDK consumers.
Was this helpful? React with 👍 or 👎 to provide feedback.


Keeps the public 402 contract aligned with the gateway's deny-visibility fix: when a submitted payment is rejected, the gateway now publishes a sanitized deny verdict on the challenge body, and consumers generating types or docs from this spec could not discover it.
While confirming the wire shape against the gateway (review follow-up), the pre-existing
error_detailmodeling turned out to be wrong: the gateway nests the bare error object directly undererror_detail({ code, message, ... }), not theErrorenvelope ({ error: { ... } }). The inner object is now extracted as a reusableErrorBodycomponent (referenced byError, so every other response's effective schema is unchanged) and the challenge composes it:payment_rejectedis optional and conditional: absent on an ordinary unpaid challenge, so existing consumers are unaffected.redocly lintpasses (pre-existing warnings only).Note
Low Risk
Documentation-only OpenAPI and changelog updates; optional additive field with no implementation changes in this repository.
Overview
Aligns the public OpenAPI contract with gateway behavior (wave-gateway#817/#818): when a client submits a payment and the gateway rejects it, the 402 x402 challenge can carry a sanitized deny verdict on
X402PaymentRequired.error_detail.error_detailis now modeled asallOfthe existingErrorref plus an optionalpayment_rejectedobject with requiredreason(closed snake_case deny vocabulary) andrail(payment rail orunknown). The field is conditional—present only on reject-after-submit, not on a normal unpaid challenge—so existing consumers that ignore unknown properties stay unaffected.CHANGELOG.mdrecords the additive schema under Unreleased.Reviewed by Cursor Bugbot for commit 740f956. Configure here.
Note
Document
error_detail.payment_rejectedon the X402 challenge bodyErrorBodyschema in openapi.yaml so theErrorenvelope andX402Challenge.error_detailcan reference the bare error object without the wrappingerrormember.payment_rejectedfield (reason,rail) toX402Challenge.error_detailto surface sanitized denial details when a submitted payment is rejected.error_detailnow referencesErrorBodydirectly rather than theErrorenvelope, meaning clients parsingerror_detailshould not expect a nestederrorkey.Macroscope summarized b51c42e.