Error Codes and Responses
This page documents all error codes returned by the Mayo ASPM API, their meanings, and how to resolve them.
All errors follow a consistent JSON structure:
{
"error": {
"code": "error_code",
"message": "Human-readable description",
"details": []
}
}
| Field |
Type |
Description |
code |
string |
Machine-readable error code |
message |
string |
Human-readable description |
details |
array |
Optional field-level validation errors |
HTTP status codes
| Status |
Meaning |
Common causes |
400 |
Bad Request |
Invalid JSON, missing required fields, invalid parameters |
401 |
Unauthorized |
Missing or invalid authentication credentials |
403 |
Forbidden |
Valid credentials but insufficient permissions |
404 |
Not Found |
Resource does not exist |
409 |
Conflict |
Resource already exists or state conflict |
422 |
Unprocessable Entity |
Valid JSON but semantic validation failed |
429 |
Too Many Requests |
Rate limit exceeded |
500 |
Internal Server Error |
Server-side error (contact support) |
502 |
Bad Gateway |
Upstream service unavailable |
503 |
Service Unavailable |
Maintenance or overloaded |
Error codes reference
Authentication errors
| Code |
HTTP Status |
Description |
Resolution |
unauthorized |
401 |
Missing or invalid credentials |
Check API key or JWT token |
token_expired |
401 |
JWT access token has expired |
Refresh using /api/auth/refresh |
token_invalid |
401 |
JWT is malformed or signature invalid |
Re-authenticate |
api_key_revoked |
401 |
API key has been revoked |
Create a new API key |
api_key_expired |
401 |
API key has passed its expiry date |
Create a new API key |
insufficient_permissions |
403 |
Key/user lacks required permission |
Check API key permissions or user role |
Validation errors
| Code |
HTTP Status |
Description |
Resolution |
validation_error |
400 |
Request body failed validation |
Check details array for field-level errors |
invalid_json |
400 |
Request body is not valid JSON |
Fix JSON syntax |
missing_field |
400 |
Required field is missing |
Add the missing field |
invalid_parameter |
400 |
Query parameter is invalid |
Check parameter format |
Example with field details:
{
"error": {
"code": "validation_error",
"message": "Request validation failed",
"details": [
{
"field": "scanners",
"message": "must contain at least one scanner"
},
{
"field": "scope",
"message": "must be one of: organization, project, asset"
}
]
}
}
Resource errors
| Code |
HTTP Status |
Description |
Resolution |
not_found |
404 |
Resource does not exist |
Verify the ID is correct |
already_exists |
409 |
Resource with that name/ID exists |
Use a different name or update the existing resource |
conflict |
409 |
Operation conflicts with current state |
Check the resource's current state |
cannot_delete |
409 |
Resource has dependencies |
Remove dependencies first (e.g., move assets before deleting project) |
Policy errors
| Code |
HTTP Status |
Description |
Resolution |
rego_parse_error |
422 |
Rego code has syntax errors |
Fix Rego syntax (line number in details) |
rego_compile_error |
422 |
Rego code compiles but has type errors |
Check variable types and rule heads |
policy_conflict |
422 |
Policy produces conflicting decisions |
Ensure rules are mutually exclusive |
invalid_policy_kind |
400 |
Unknown policy kind |
Use: triage, priority, ownership, project, pr_scan |
invalid_package |
422 |
Package doesn't match policy kind |
Use mayo.triage, mayo.priority, etc. |
Scan errors
| Code |
HTTP Status |
Description |
Resolution |
scan_already_running |
409 |
A scan is already in progress for this scope |
Wait for the current scan to complete |
scan_limit_exceeded |
429 |
Scan limit for your tier reached |
Wait or upgrade your plan |
clone_failed |
500 |
Failed to clone repository |
Check GitHub App permissions |
scanner_timeout |
500 |
Scanner exceeded time limit |
Reduce scan scope or check repo size |
Rate limit errors
| Code |
HTTP Status |
Description |
Resolution |
rate_limited |
429 |
Too many requests |
Wait for Retry-After seconds |
Debugging errors
Include request IDs
Every response includes a X-Request-ID header:
X-Request-ID: req_a1b2c3d4e5f6
Include this ID when contacting support — it helps locate your request in the logs.
Verbose error mode
Add ?verbose=true to any request to get extended error details:
curl "https://mayoaspm.com/api/policies?verbose=true" \
-H "Authorization: Bearer mayo_ak_..."
This includes stack context and suggestion text in error responses (non-production use recommended).
Common patterns
Retry strategy by status code
| Status |
Retry? |
Strategy |
| 400 |
No |
Fix the request |
| 401 |
Maybe |
Refresh token, then retry once |
| 403 |
No |
Check permissions |
| 404 |
No |
Fix the resource ID |
| 429 |
Yes |
Wait for Retry-After |
| 500 |
Yes |
Retry with exponential backoff (max 3 times) |
| 502/503 |
Yes |
Retry after 30 seconds |
Next steps