API error design patterns. An extension skill for doc-writer/mock-tester that provides error code systems, error response structures, client-friendly error messages, error catalog construction, and retry/fallback strategies. Use when designing API error handling systems involving 'API error design', 'error codes', 'error responses', 'error catalogs', 'error messages', 'retry strategies', etc. Note: actual error handling code implementation is outside the scope of this skill.
Scanned 5/29/2026
Install via CLI
openskills install sideprojectmate/sideProjectMate---
name: api-error-design
description: "API error design patterns. An extension skill for doc-writer/mock-tester that provides error code systems, error response structures, client-friendly error messages, error catalog construction, and retry/fallback strategies. Use when designing API error handling systems involving 'API error design', 'error codes', 'error responses', 'error catalogs', 'error messages', 'retry strategies', etc. Note: actual error handling code implementation is outside the scope of this skill."
---
# API Error Design — API Error Design Patterns
A reference for error systems, message design, and recovery strategies used by the doc-writer and mock-tester agents when designing API error documentation and tests.
## Target Agents
- `doc-writer` — Applied when writing error reference documentation
- `mock-tester` — Applied when designing error scenario tests
## Error Code System Design
### Hierarchical Error Code Structure
```
{DOMAIN}_{CATEGORY}_{DETAIL}
Examples:
AUTH_TOKEN_EXPIRED -- Authentication > Token > Expired
ORDER_PAYMENT_DECLINED -- Order > Payment > Declined
USER_VALIDATION_EMAIL -- User > Validation > Email
```
### Error Code Catalog by Domain
#### Authentication/Authorization (AUTH)
| Code | HTTP | Message | Client Action |
|------|------|---------|---------------|
| AUTH_REQUIRED | 401 | Authentication is required | Redirect to login page |
| AUTH_TOKEN_EXPIRED | 401 | Token has expired | Attempt token refresh |
| AUTH_TOKEN_INVALID | 401 | Invalid token | Re-authenticate |
| AUTH_FORBIDDEN | 403 | You do not have permission for this action | Guide user to request permissions |
| AUTH_ACCOUNT_LOCKED | 403 | Account is locked. Please retry after 15 minutes | Display wait timer |
| AUTH_INVALID_CREDENTIALS | 401 | Invalid email or password | Prompt re-entry |
#### Validation (VALIDATION)
| Code | HTTP | Message | Field-Level Detail |
|------|------|---------|-------------------|
| VALIDATION_REQUIRED | 422 | Required field is missing | The `{field}` field is required |
| VALIDATION_FORMAT | 422 | Invalid format | Please enter a valid `{type}` |
| VALIDATION_RANGE | 422 | Value is out of range | Please enter a value between `{min}` and `{max}` |
| VALIDATION_UNIQUE | 409 | Value is already in use | This `{field}` is already registered |
| VALIDATION_LENGTH | 422 | Length limit exceeded | Please enter no more than `{max}` characters |
#### Resource (RESOURCE)
| Code | HTTP | Message |
|------|------|---------|
| RESOURCE_NOT_FOUND | 404 | The requested resource was not found |
| RESOURCE_ALREADY_EXISTS | 409 | Resource already exists |
| RESOURCE_DELETED | 410 | Resource has been deleted |
| RESOURCE_LOCKED | 423 | Resource is locked |
#### Rate Limit
| Code | HTTP | Message |
|------|------|---------|
| RATE_LIMIT_EXCEEDED | 429 | Request limit exceeded. Please retry after {retryAfter} seconds |
#### Server (SERVER)
| Code | HTTP | Message |
|------|------|---------|
| SERVER_INTERNAL | 500 | A server error occurred. Please retry shortly |
| SERVER_MAINTENANCE | 503 | Service is under maintenance |
| SERVER_UPSTREAM | 502 | Failed to connect to an external service |
## Error Response Structure Standard
### Basic Structure
```json
{
"error": {
"code": "AUTH_TOKEN_EXPIRED",
"message": "Token has expired",
"detail": "The access token has expired. Please refresh using your refresh token.",
"timestamp": "2025-03-15T09:30:00Z",
"requestId": "req_abc123def456",
"path": "/api/v1/users/me"
}
}
```
### Validation Error (Per-Field)
```json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Input values are invalid",
"errors": [
{
"field": "email",
"code": "VALIDATION_FORMAT",
"message": "Please enter a valid email address",
"value": "invalid-email"
},
{
"field": "password",
"code": "VALIDATION_LENGTH",
"message": "Password must be at least 8 characters",
"constraint": { "min": 8 }
}
]
}
}
```
## Error Message Writing Principles
### Three Elements of a Good Error Message
1. **What went wrong** — Describe the problem
2. **Why it went wrong** — Explain the cause or constraint
3. **How to fix it** — Provide a specific action
### Do / Don't
| Don't | Do |
|-------|---|
| "Error occurred" | "Failed to create the order" |
| "Invalid input" | "Price must be a number greater than 0" |
| "Server error: NullPointerException at..." | "A server error occurred. Please retry shortly" |
| "Access denied" | "You do not have permission to modify this order. Please contact an administrator" |
| "Duplicate key constraint violation" | "This email is already registered" |
### Multilingual Error Message Structure
```json
{
"error": {
"code": "VALIDATION_REQUIRED",
"message": "Required field is missing",
"messageKey": "error.validation.required",
"params": { "field": "email" }
}
}
```
## Retry/Fallback Strategy
### Retry Eligibility
| HTTP Status | Retryable? | Strategy |
|-------------|-----------|----------|
| 408 | Yes | Retry immediately |
| 429 | Yes | Wait per Retry-After header |
| 500 | Yes (conditional) | Exponential backoff |
| 502, 503, 504 | Yes | Exponential backoff |
| 400, 401, 403, 404 | No | Client-side fix required |
| 409, 422 | No | Input correction required |
### Exponential Backoff
```
wait_time = min(baseDelay * 2^attempt + jitter, maxDelay)
Example: baseDelay=1s, maxDelay=30s
Attempt 1: 1s + random(0~500ms)
Attempt 2: 2s + random(0~500ms)
Attempt 3: 4s + random(0~500ms)
Attempt 4: 8s + random(0~500ms)
Maximum 3-5 attempts
```
## Error Test Scenario Matrix
| Category | Test Case | Expected Code |
|----------|-----------|---------------|
| No authentication | Request without Authorization header | 401 |
| Expired token | Request with expired JWT | 401 |
| No permission | Access another user's resource | 403 |
| Non-existent ID | Query with random UUID | 404 |
| Missing required field | Remove required field from body | 422 |
| Invalid format | "abc" in email field | 422 |
| Duplicate creation | POST same data twice | 409 |
| Bulk requests | Exceed Rate Limit | 429 |
| Malformed JSON | Send `{invalid json` | 400 |
| Empty body | Content-Length: 0 | 400 |
No comments yet. Be the first to comment!