@rail402.dev/errors, which the facilitator, the Bazaar, the MCP server, and the SDK all share.
The shape
Every rejection is a{ code, reason, retryable } object.
The guarantee: every rejection across the facilitator, the Bazaar, and the MCP server carries a non-null
reason. There is no null, empty, or missing reason anywhere. An agent can reason about a failure without parsing prose.Handling errors
@rail402.dev/errors (also at @rail402.dev/sdk/errors) exports the registry and the helpers.
The SDK’s buyer functions surface the same shape as
result.error, so you branch on code the same way whether you caught an X402Error or read a Result.
Retryable means retryable
retryable: true is reserved for genuinely transient conditions, such as rate limiting or a network submission failure. Everything else is false. Respect the flag. Retrying a non-retryable failure loops forever, and one code in particular means the money already moved, so a retry pays twice.
Notable codes
A small slice of the registry, covering the failures you meet first. UseALL_ERROR_CODES and ERROR_REGISTRY to enumerate the full set at runtime.
Next steps
Troubleshooting
Symptom, cause, and fix for the common failures.
SDK reference
Where these codes surface in
result.error.FAQ
Answers to the questions behind many rejections.
Packages
Where the errors package fits.