From harness-claude
Defines consistent API error contracts with machine-readable codes, human-readable messages, remediation advice, taxonomy, and envelope structure. Use for API design, PR reviews, style guides, audits, SDKs, and OpenAPI docs.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> ERROR CONTRACTS DEFINE THE MACHINE-READABLE STRUCTURE, HUMAN-READABLE MESSAGE, AND ACTIONABLE REMEDIATION FOR EVERY FAILURE MODE — CONSISTENT ERROR RESPONSE DESIGN LETS CLIENTS HANDLE ERRORS PROGRAMMATICALLY WITHOUT PARSING FREE-TEXT OR REVERSE-ENGINEERING FAILURE SEMANTICS.
Guides implementation of RFC 9457 Problem Details for HTTP API error responses using application/problem+json with type URI, title, status, detail, and instance fields. Useful for REST APIs, microservices, gateways, and OpenAPI specs.
Implements standardized API error handling with RFC 7807 responses, typed error classes, middleware, and monitoring. Use for consistent HTTP errors across endpoints.
Implements API error handling with standardized responses, logging, monitoring, retry logic, circuit breakers, and validation patterns for Node.js and Python APIs.
Share bugs, ideas, or general feedback.
ERROR CONTRACTS DEFINE THE MACHINE-READABLE STRUCTURE, HUMAN-READABLE MESSAGE, AND ACTIONABLE REMEDIATION FOR EVERY FAILURE MODE — CONSISTENT ERROR RESPONSE DESIGN LETS CLIENTS HANDLE ERRORS PROGRAMMATICALLY WITHOUT PARSING FREE-TEXT OR REVERSE-ENGINEERING FAILURE SEMANTICS.
CARD_DECLINED) and HTTP status codes for client routingMachine-readable error codes — An application-level error code ("code": "INSUFFICIENT_FUNDS") is distinct from the HTTP status code. It identifies the specific failure type within a category so clients can branch on it without parsing free-text messages. Example: two Stripe 402 responses may have "code": "card_declined" or "code": "expired_card" — the HTTP status routes to the payment-failure handler; the code selects the message shown to the user.
Human-readable messages — The message field is for developers reading logs or API explorer output, not for display in end-user interfaces. It should be complete and unambiguous: "The card ending in 4242 was declined by the issuer" rather than "Card error". Avoid exposing internal implementation details, stack traces, or database error messages.
Actionable remediation — Every error response should answer: "What should the caller do next?" The "detail" field (per RFC 9457) or a dedicated "suggestion" field communicates the next step: "Retry with a different payment method", "Check that the field matches ISO 8601 format", or "Contact support with reference ID abc-123". Errors without remediation guidance shift the debugging burden to the caller.
Error taxonomy — Group error codes into categories that map to HTTP status classes: authentication errors (401), authorization errors (403), validation errors (422), business-rule violations (409/422), and server faults (500). A taxonomy prevents code proliferation and makes documentation searchable. Publish the full taxonomy in API reference docs; include a type URI (per RFC 9457) so clients can link to the documentation for each error type.
Consistent envelope structure — Every error response from every endpoint must use the same JSON shape. Mixing { "error": "..." }, { "message": "...", "errors": [...] }, and { "code": ..., "description": ... } across endpoints breaks SDK code generation and forces client-side shape detection. Choose one envelope (RFC 9457 Problem Details is the recommended standard) and enforce it at the framework/middleware level.
Error reference IDs — For server-side faults (5xx), include a unique instance or traceId field that correlates the response to a specific log entry. This enables support teams to locate the root cause without asking users to reproduce the issue. Example: "instance": "/errors/7f3a-bc91-..." or "traceId": "abc-123-xyz".
Stripe's error contract is one of the most studied in production APIs. It uses a consistent envelope across all failure modes:
Payment declined (402 Payment Required):
POST /v1/charges
Authorization: Bearer sk_example_...
Content-Type: application/x-www-form-urlencoded
amount=2000¤cy=usd&source=tok_chargeDeclined
HTTP/1.1 402 Payment Required
Content-Type: application/json
{
"error": {
"type": "card_error",
"code": "card_declined",
"decline_code": "insufficient_funds",
"message": "Your card has insufficient funds.",
"param": "source",
"charge": "ch_3N..."
}
}
Invalid API key (401 Unauthorized):
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
"error": {
"type": "authentication_error",
"code": "api_key_invalid",
"message": "No such API key: sk_example_****abc.",
"doc_url": "https://stripe.com/docs/error-codes/api-key-invalid"
}
}
Missing required parameter (400 Bad Request):
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": {
"type": "invalid_request_error",
"code": "parameter_missing",
"message": "Missing required param: amount.",
"param": "amount",
"doc_url": "https://stripe.com/docs/error-codes/parameter-missing"
}
}
Stripe's taxonomy (card_error, authentication_error, invalid_request_error, api_error, idempotency_error) maps cleanly to HTTP status ranges. The code field gives a programmatic subcategory; param identifies the offending field; doc_url links to remediation. SDK clients switch on error.type for top-level routing and error.code for specific handling — without any free-text parsing.
Free-text error strings only. { "error": "Something went wrong" } or { "message": "Invalid input" } forces clients to parse English prose to determine the error type. Localization, rewording, or phrasing changes in the message silently break clients that pattern-match on strings. Fix: always include a machine-readable code field alongside the human-readable message.
Inconsistent envelope shape across endpoints. When one endpoint returns { "error": { "message": "..." } } and another returns { "errors": ["..."] } and a third returns { "status": "error", "reason": "..." }, client error handling requires per-endpoint special cases. Fix: enforce a single error shape at the middleware or gateway layer so every response is shaped identically before leaving the server.
Leaking internal error details. Including "sqlState": "23000", "stackTrace": "...", or "internalMessage": "NullPointerException at line 42" in error responses exposes implementation internals, aids attackers, and creates API surface that clients may start depending on. Fix: log internal details server-side and surface only a traceId for correlation. The public error contains only what is safe and useful for the caller.
Omitting actionable remediation. An error like { "code": "RATE_LIMITED" } without a Retry-After header or a detail explaining when to retry is incomplete. The caller either retries immediately (worsening the rate-limit problem) or gives up unnecessarily. Fix: every error response should include what the caller should do next — retry timing, which parameter to fix, or where to get help.
Error codes should use consistent casing (SCREAMING_SNAKE_CASE for application codes is common; snake_case is used by Stripe and GitHub). Codes must be stable across API versions — changing CARD_DECLINED to PAYMENT_DECLINED is a breaking change for any client that switches on the code. Prefix codes by domain when the taxonomy is large: AUTH_TOKEN_EXPIRED, PAYMENT_CARD_DECLINED, VALIDATION_FIELD_REQUIRED.
Every published error code should be documented with: the HTTP status code it accompanies, a description of when it occurs, the fields present in the response for this code, and recommended client action. This documentation is the contract — treat removals or renames as breaking changes.
Twilio maintains a published error dictionary at twilio.com/docs/api/errors with over 600 documented error codes. Each code has a dedicated page with: description, possible causes, and suggested resolution steps. When Twilio's REST API returns an error, it includes "code": 21211 (for example) alongside the HTTP 400 status. Clients look up the code in documentation or switch on it directly. Twilio's developer surveys show that APIs with published error taxonomies reduce average debugging time by 40-60% compared to APIs that return only HTTP status codes and free-text messages. The combination of stable machine-readable codes and linked documentation is the highest-leverage investment in API error design.
4xx/5xx response schemas.harness validate to confirm skill files are well-formed and related skills are correctly cross-referenced.code field alongside the human-readable message.5xx response includes a traceId or instance field for log correlation.