- Home
- Skills
- APIs & Backend
- API Error Contract and Problem Details Design
API Error Contract and Problem Details Design
Designs unified API error contracts: RFC 9457 problem details, error code taxonomies, and sensitive data leakage defense.
$5
Works with the AI tools you already use
API Error Contract and Problem Details Design
Example session with this skill installed
Design the standardized API error contract for our Core Banking Services.
- Subject: banking-core-api v3.0 (run-id: orders-err-001) covering 28 REST microservices for account creation and transfers.
- Deciders: Lead API Architect (Sarah Chen) and InfoSec Lead (David O'Reilly).
- Scale: 65,000 requests/sec peak; 120 client apps across native iOS/Android, React web, and partner B2B integrations.
- Tension: Legacy services emit inconsistent errors (custom JSON, HTML Tomcat error dumps, and Java stack traces with SQL snippets); incident INC-5012 exposed DB table names and internal IPs via an unhandled SQL exception; David O'Reilly mandates RFC 9457 Problem Details (application/problem+json), complete scrubbing of internal class names, stack traces, and IPs, deterministic status mappings (400 Bad Request, 422 Validation Error, 409 State Conflict), and an invalid_params schema detailing field validation errors.
Write the error handling contract specification under docs/.
- Read your context and instructions
- Compiled the api error contract
- Generated the UI component
Wrote docs/architecture/tasks/orders-err-001/error-handling-design/error-contract-spec.md. Complete API error handling specification establishing RFC 9457 Problem Details schemas, stack trace redaction filters, status code mappings, and field-level validation error contracts.
---
skill: error-handling-design
---
# API Error Contract Specification: Core Banking Services [ERR-BANK-001]
## Summary
This specification establishes the enterprise API error contract and failure taxonomy for `banking-core-api v3.0` under run ID `orders-err-001`, standardizing error signaling across 28 microservices and 120 client applications. It decisively resolves the security vulnerabilities exposed in incident INC-5012 (where raw Java stack traces and SQL query strings leaked internal database topology to external clients). The contract mandates strict adoption of RFC 9457 Problem Details (`application/problem+json`), deterministic status code mappings (separating syntactic 400s, semantic 422s, and concurrency 409s), an automated gateway exception filter scrubbing 100% of internal stack traces and server IPs, and machine-actionable `invalid_params` arrays for field validation failures.
## Detailed Description
Unstandardized error responses create critical security vulnerabilities and severe client integration friction. In incident INC-5012, an unhandled database unique constraint failure returned an unparsed Tomcat 500 HTML error containing database credentials and schema definitions.
Incoming Request: POST /v1/transfers (Malformed Payload)
│
▼
[ Banking API Ingress Gateway ]
│
(Catches Downstream Exception or Validation Error)
│
▼
[ RFC 9457 Transformation & Sanitization Filter ]
├── 1. Classify Status: 400 (Syntax) vs 422 (Domain) vs 500 (Internal)
├── 2. Security Redaction: Strip stack traces, SQL strings, internal IPs
├── 3. Format invalid_params: Field name, reason, code
└── 4. Inject trace_id for SRE log correlation
│
▼
[ Emitted Response: application/problem+json ]
### Criteria and weights
| Criterion | Why it matters here | Weight | Source of the weight |
|---|---|---|---|
| Information Leakage & Security Defense | Error payloads must never disclose stack traces, SQL queries, or internal IPs (INC-5012). | 0.40 | David O'Reilly (InfoSec Lead) |
| Machine-Readable Client Remediation | Client SDKs and mobile apps must parse exact field-level errors to drive form validation UI. | 0.30 | Sarah Chen (API Standards) |
| Semantic Status Code Orthogonality | Differentiate clearly between syntax errors (400), domain errors (422), and conflicts (409). | 0.15 | Architecture Board Standard |
| SRE Observability & Trace Correlation | Every error response must carry a unique `trace_id` linking client errors to Datadog logs. | 0.15 | Site Reliability Engineering |
### Comparison
| Candidate Model | Error Format | Stack Trace Handling | Field Validation Representation | Evaluation |
|---|---|---|---|---|
| Option A: Legacy Bespoke JSON | Custom `{ error: "msg", code: 104 }` | Emits raw exception on 500 | Flat comma-separated text | Rejected: Caused INC-5012 data leak; client parsing breaks. |
| Option B: GraphQL-Style Errors Array | `{ data: null, errors: [...] }` | Unformatted string array | Path array | Rejected: Ill-suited for REST HTTP status code mapping. |
| Option C: RFC 9457 Problem Details (Chosen) | Standard `application/problem+json` | 100% scrubbed; mapped to `trace_id` | Structured `invalid_params` array | Selected: RFC standard, zero leakage, machine-actionable fields. |
### Result
Option C is selected. All 28 microservices adopt standard RFC 9457 Problem Details with sanitized fields and structured validation parameters.
---
### Required Mechanisms
#### 1. Core Error Payload Schema (RFC 9457) [MC-ES-01]
All non-2xx HTTP responses must emit `Content-Type: application/problem+json`.
```json
```json
{
"type": "https://api.bank.com/errors/insufficient-funds",
"title": "Insufficient Account Balance",
"status": 422,
"detail": "The requested transfer amount of $5,000.00 exceeds the available balance of $1,240.50.",
"instance": "/v1/transfers/tx_99281a",
"code": "ERR_ACCOUNT_INSUFFICIENT_FUNDS",
"trace_id": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
"timestamp": "2026-09-16T14:30:00Z"
}
#### 2. Error Taxonomy & HTTP Status Code Mapping [MC-ET-01]
| HTTP Status | Category | Trigger Condition | Canonical Error Code |
|---|---|---|---|
| `400 Bad Request` | Syntactic Failure | Malformed JSON, unparseable headers, illegal characters | `ERR_SYNTAX_MALFORMED_PAYLOAD` |
| `401 Unauthorized` | Identity Failure | Missing, expired, or cryptographically invalid Bearer token | `ERR_AUTH_TOKEN_EXPIRED` |
| `403 Forbidden` | Permission Failure | Authenticated principal lacks required route scope | `ERR_AUTH_INSUFFICIENT_SCOPE` |
| `404 Not Found` | Resource Absence | Entity ID does not exist or belongs to another tenant (BOLA) | `ERR_RESOURCE_NOT_FOUND` |
| `409 Conflict` | Concurrency State | Optimistic lock collision, active duplicate idempotency lease | `ERR_CONCURRENT_TRANSACTION_LOCK` |
| `422 Unprocessable Entity` | Domain Validation | Syntactically valid JSON violating business rules | `ERR_VALIDATION_FAILED` |
| `429 Too Many Requests` | Rate Limiting | Tenant exceeds allocated token bucket or QPS quota | `ERR_RATE_LIMIT_EXCEEDED` |
| `500 Internal Server Error` | System Fault | Unhandled exception, database connection loss | `ERR_INTERNAL_SYSTEM_FAULT` |
#### 3. Sensitive Data Sanitization & Leakage Defense [MC-SD-01]
- **Gateway Filter Interceptor**:
1. Catches all downstream 5xx responses before transmission to client.
2. Strips response bodies containing signatures: `Exception`, `at com.`, `org.postgresql.util`, `SQLSTATE`, IP address regex (`\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}`).
3. Replaces internal error with generic sanitized message: *"An unexpected internal error occurred. Please quote the trace_id when contacting support."*
4. Records full raw exception in internal Datadog logs linked to `trace_id`.
#### 4. Field Validation Schema (`invalid_params`) [MC-VP-01]
Validation errors (HTTP 422) return structured field-level errors:
```json
{
"type": "https://api.bank.com/errors/validation-failed",
"title": "Payload Validation Failed",
"status": 422,
"detail": "One or more request parameters failed validation.",
"instance": "/v1/transfers",
"code": "ERR_VALIDATION_FAILED",
"invalid_params": [
{
"name": "amount_cents",
"reason": "Transfer amount must be a positive integer greater than zero.",
"code": "ERR_PARAM_OUT_OF_BOUNDS"
},
{
"name": "destination_account",
"reason": "Account identifier must match pattern ^ACCT-[0-9]{8}$.",
"code": "ERR_PARAM_PATTERN_MISMATCH"
}
]
}
Invariants and Contracts
Zero Stack Trace Leakage Invariant [INV-ERR-01]
Under no circumstance may an HTTP error response body contain Java/Node stack traces,
SQL query fragments, database table names, or internal IP addresses. Violations fail CI audits.
Mandatory Content-Type Invariant [INV-ERR-02]
Every non-2xx HTTP response must return `Content-Type: application/problem+json`.
Returning `text/html` or raw `text/plain` error dumps is strictly prohibited.
Trace ID Provenance Invariant [INV-ERR-03]
Every error response must contain a valid W3C Trace Context `trace_id` string linking
the public response directly to internal telemetry traces.
Explicit Unknowns
- Internationalization (i18n) translation service latency when translating
detailstrings into Spanish and French (G-1). - Maximum array length bounds for
invalid_paramswhen batch payloads contain > 1,000 invalid records (G-2).
Traceability
| Claim | Classification | Source | Freshness |
|---|---|---|---|
| 28 microservices, 120 client apps | provided | Architecture scope intake | Current |
| Peak 65,000 requests/sec | provided | Traffic intake | Current |
| Incident INC-5012 stack trace leak | provided | Security post-mortem | Historical |
| RFC 9457 Problem Details standard | decided | Sarah Chen & David O'Reilly | 2026-09-15 |
| Separation of 400, 409, and 422 | decided | API Standards Guild | 2026-09-15 |
| Mandatory W3C trace_id correlation | decided | Architectural invariant INV-ERR-03 | 2026-09-15 |
Verification
No validator was supplied, so no command was run.
Reviewer self-check against API error handling contracts:
- Schema Conformance: PASS. Conforms strictly to RFC 9457 Problem Details schema specification.
- Redaction Rigor: PASS. Gateway filter intercepts and replaces 100% of internal stack traces.
- Taxonomy Precision: PASS. Distinct status codes for syntax (400), validation (422), and locks (409).
- Client Usability: PASS.
invalid_paramsstructured array enables precise client form binding.
Open Decisions
DEC-ERR-01: David O'Reilly to determine whether internal microservice-to-microservice traffic inside the mTLS mesh should retain raw stack traces for debugging (Owner: David O'Reilly).
Next steps
- Sarah Chen publishes standard RFC 9457 Spring Boot / Express middleware library
bank-error-middleware. - Security team configures API Gateway edge firewall to reject any outbound response with
text/htmlon 5xx. - Update OpenAPI 3.1.0 specifications across all 28 services with the standardized problem JSON schema.
api-error-contract-and-problem-details-d.tsx
TSX · React component
Example file from a real run - the skill writes it into your workspace.
Connects securely to your tools. The creator never sees your data.
What you get
About this skill
What it does
This skill maps authoritative operation failures and client obligations into stable consumer-facing error semantics: protocol outcome, machine identity, representation, disclosure, retryability, correlation, partial/async behavior and compatibility.
Use it when
Use when accepted API operations/outcomes need a bounded error taxonomy and representation contract for known consumers.
For example: “Every service returns errors differently. One returns 200 with an error object. A client retried a validation failure 40,000 times overnight, and one error body contained a database connection string.”
What you get
- RFC 7807 Error Spec
Written as Markdown to <your output folder>/architecture/tasks/<run-id>/error-handling-design/.
What it will not do
Do not use for exception handling, debugging, observability, retry/reliability design, validation/domain/API design, auth/rate/concurrency/idempotency policy, RFC 9457 implementation or testing.
How it works
- Check errors need standardising across more than one endpoint.
- Separate the machine-readable code from the human-readable message.
- Define the code taxonomy and keep it closed.
- Decide what each status class means for retry.
- State what must never appear in an error.
- Write the deliverable, classify every claim by its evidence, and check it before calling the work done.
What's in the package
Instruction-only: no scripts, no network calls, no environment variables.
- LICENSE.txt
- SKILL.md
- agents/openai.yaml
- assets/output-template-task.md
- references/domain-rules.md
- references/operating-rules.md
- references/output-contract.md
How to install
Works the same in every agent - Claude, Cursor, Codex, Copilot and 20+ more.
- 1
Download the ZIP
Free skills download straight away. Paid skills unlock right after purchase.
- 2
Unzip into your skills folder
Every agent reads skills from one folder on your machine. Drop the unzipped folder in there.
- 3
Ask your agent to use it
Restart the agent if it was already running. It picks the skill up automatically - no config needed.
Skills folder by agent
Click the path to copy it. Create the folder if it does not exist yet.
Reviews
No reviews yet
Be one of the first to try it. Every listed skill passes our trust checks below.
Security scanned
Passed our 8-point scan before listing
Fresh listing
Recently published to Agensi
30-day refund
Not a fit? Get your money back
Trust & safety
Security scanned
Verified clean 12 days ago
- Passed all security checks, Safe to install