Skip to main content

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-readable message 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 the errors 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:
The 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 the X-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

The message 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 on 429 (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.