{"catalog":"vaultfire-x402-errors","version":"1.0","description":"Stable machine-readable catalog of every error code emitted by Vaultfire x402 endpoints. Codes never change once published; deprecated codes carry deprecated:true. Agents should consume this once and treat error.code as the authoritative branching key.","docs":"https://theloopbreaker.com/docs/errors","count":20,"categories":["payment","validation","authentication","rate-limit","replay","contract","chain","deprecation","not-found","server"],"errors":[{"code":"VF-PAY-001","httpStatus":402,"category":"payment","retryable":true,"message":"X-PAYMENT header is required","agentAction":"Build an x402 payment header per the schema in `accepts[0]` and resubmit. Sign EIP-3009 USDC authorization locally; never send a private key."},{"code":"VF-PAY-002","httpStatus":402,"category":"payment","retryable":true,"message":"Payment header malformed — base64 decode or JSON parse failed","agentAction":"Re-encode the payment payload as base64(JSON) and resubmit. See /api/x402/agent-guide for the canonical encoding."},{"code":"VF-PAY-003","httpStatus":402,"category":"payment","retryable":true,"message":"Payment scheme mismatch — endpoint expects scheme=exact","agentAction":"Set scheme=\"exact\" in the payment payload. Vaultfire does not support streaming or commit/reveal schemes."},{"code":"VF-PAY-004","httpStatus":402,"category":"payment","retryable":true,"message":"Payment amount below required minimum","agentAction":"Read maxAmountRequired from accepts[0] and resubmit with matching amount in atomic units (6-decimal USDC)."},{"code":"VF-PAY-005","httpStatus":402,"category":"payment","retryable":false,"message":"Payment signature invalid — EIP-712 recovery failed","agentAction":"Verify EIP-712 domain (name, version, chainId, verifyingContract) matches the values in accepts[0].extra. Re-sign and resubmit. Same nonce CANNOT be reused."},{"code":"VF-VAL-001","httpStatus":400,"category":"validation","retryable":false,"message":"Request body is not valid JSON","agentAction":"Set Content-Type: application/json and submit a valid JSON body. Fields must match inputSchema.bodyFields."},{"code":"VF-VAL-002","httpStatus":400,"category":"validation","retryable":false,"message":"Required field missing or invalid","agentAction":"Inspect inputSchema.bodyFields[*].required and resubmit with all required fields. Types must match (address, uint256, string, etc.)."},{"code":"VF-VAL-003","httpStatus":400,"category":"validation","retryable":false,"message":"Address field is not a valid 0x-prefixed 20-byte address","agentAction":"Format addresses as `0x` + 40 hex chars (mixed case OK). Use ENS only after resolving to a hex address client-side."},{"code":"VF-VAL-004","httpStatus":400,"category":"validation","retryable":false,"message":"Chain field is unsupported","agentAction":"Choose from chainsAvailable in the spec. Currently: base, polygon, avalanche, arbitrum (subset varies per action)."},{"code":"VF-VAL-005","httpStatus":422,"category":"validation","retryable":false,"message":"Field rejected — looks like a private key, secret, or seed","agentAction":"Vaultfire NEVER accepts private keys. Remove any field shaped like privateKey, secret, mnemonic, seed and resubmit. All signing must happen in the caller wallet."},{"code":"VF-AUTH-001","httpStatus":401,"category":"authentication","retryable":false,"message":"Caller address does not match payment signer","agentAction":"The wallet that signed the x402 payment must equal walletAddress in the body. Re-sign with the correct key."},{"code":"VF-RATE-001","httpStatus":429,"category":"rate-limit","retryable":true,"retryAfterSeconds":60,"message":"Rate limit exceeded for this IP / API path","agentAction":"Honor the Retry-After response header. Default limits: 20/min on writes, 60/min on reads. Spread requests across more than 60 seconds."},{"code":"VF-REPLAY-001","httpStatus":409,"category":"replay","retryable":false,"message":"Nonce already used","agentAction":"Generate a fresh random 32-byte nonce. The same EIP-3009 authorization can only be redeemed once per chain."},{"code":"VF-REPLAY-002","httpStatus":409,"category":"replay","retryable":false,"message":"Authorization expired (validBefore in the past)","agentAction":"Re-sign with a fresh validBefore at least 60 seconds in the future. Default window is 5 minutes."},{"code":"VF-CONTRACT-001","httpStatus":422,"category":"contract","retryable":false,"message":"On-chain precondition failed (e.g. msg.value below required stake, agent not registered, already vouched)","agentAction":"Read the `reverts[]` array in the spec to see common preconditions. Inspect agent state via /api/x402/trust/agent-status before retrying."},{"code":"VF-CONTRACT-002","httpStatus":422,"category":"contract","retryable":false,"message":"eth_estimateGas reverted — tx would revert if broadcast","agentAction":"Vaultfire pre-simulates every tx. The error.reason field carries the revert reason. Fix the input and retry."},{"code":"VF-CHAIN-001","httpStatus":503,"category":"chain","retryable":true,"retryAfterSeconds":15,"message":"Upstream RPC unavailable","agentAction":"Wait and retry. Vaultfire auto-fails-over across multiple RPC providers; sustained 503 indicates chain-wide outage."},{"code":"VF-DEPRECATED-001","httpStatus":410,"category":"deprecation","retryable":false,"message":"This endpoint is deprecated; use the canonical endpoint instead","agentAction":"Read the `canonical` field in the response and switch to that URL. Old endpoint will be removed on the published sunset date."},{"code":"VF-NOT-FOUND-001","httpStatus":404,"category":"not-found","retryable":false,"message":"Resource not found (agent / bond / task does not exist)","agentAction":"Verify the on-chain entity exists via the relevant /trust/* read endpoint before mutating."},{"code":"VF-SERVER-001","httpStatus":500,"category":"server","retryable":true,"retryAfterSeconds":5,"message":"Internal server error","agentAction":"Retry with exponential back-off. If sustained for more than 60 seconds, hit /api/x402/trust/health for protocol status."}]}