Error Handling
The JJHub API uses a consistent, Gitea-compatible error format across all endpoints. Every error response is a JSON object with a human-readablemessage and an optional errors array containing field-level details.
Error Response Structure
All API errors follow this shape:
When no field-level errors apply, the
errors array is omitted from the response body.
HTTP Status Codes
Field Error Codes
When theerrors array is present, each entry contains a code field with one of the following values:
Example Error Responses
Validation Error (422)
A request to create an issue without a title:Not Found (404)
A request for a repository that does not exist:Authentication Error (401)
A request with an invalid or expired token:Permission Error (403)
A request to delete a repository the user does not own:Conflict (409)
A request to create a repository with a name that already exists:Multiple Field Errors (422)
A request with several invalid fields:Rate Limiting (429)
When you exceed the rate limit, the response includes headers indicating when you can retry:X-RateLimit-Reset value is a Unix timestamp indicating when the rate limit window resets. Authenticated requests are limited to 5,000 per hour. Unauthenticated requests are limited to 60 per hour. Search endpoints have a separate limit of 30 requests per minute.
Best Practices
Check the status code first
Use the HTTP status code to determine the category of error before parsing the body. This lets you handle broad error classes (auth failures, not found, server errors) without parsing JSON.Use the errors array for user-facing messages
When the errors array is present, use it to display specific field-level feedback. The resource, field, and code triple gives you enough information to map errors to form fields or CLI flags.
Handle rate limits gracefully
Read theX-RateLimit-Remaining header on every response. When it reaches zero, wait until the X-RateLimit-Reset timestamp before sending more requests. For automated clients, implement exponential backoff on 429 responses.
Do not rely on error message text
Themessage field is intended for human readers and may change without notice. Build your error-handling logic around status codes and errors[].code values, which are part of the stable API contract.
Retry only on appropriate errors
Only retry on429 (after respecting the rate limit reset time) and 500/504 (with exponential backoff). Do not retry 400, 401, 403, 404, 409, or 422 responses, as these indicate client-side problems that will not resolve by retrying.