Errors
TL;DR: errors carry a stable code from the ErrorCode enum, a human-readable message, and an HTTP status determined by a fixed code-to-status map.
Error code reference
| Code | HTTP status | Meaning |
|---|---|---|
| VALIDATION_ERROR | 422 | Generic semantic validation failure. |
| SCHEMA_ERROR | 422 | Request shape does not match the expected schema. |
| MATRIX_SIZE_MISMATCH | 422 | Distance/time matrix is not square or does not match referenced indices. |
| UNKNOWN_LOCATION_INDEX | 422 | A location index is referenced that is out of range for the matrix. |
| UNKNOWN_REFERENCE | 422 | An ID (resource, job, depot) is referenced that does not exist. |
| DUPLICATE_ID | 422 | Two entities in the same list share an ID. |
| INVALID_TIME_WINDOW | 422 | A time window has end < start. |
| INFEASIBLE_REQUEST | 422 | Request is structurally infeasible before solving is even attempted. |
| CIRCULAR_PRECEDENCE | 422 | Precedence relations form a cycle. |
| MISSING_MATRIX | 422 | Neither matrices nor a routing profile were supplied. |
| INVALID_CAPACITY_SPEC | 422 | Capacity/demand dict and shorthand int forms are mixed inconsistently. |
| JOB_NOT_FOUND | 422 | A referenced job ID does not exist in the request (e.g. in locks or relations). |
| VEHICLE_NOT_FOUND | 422 | A referenced resource ID does not exist. |
| DEPOT_NOT_FOUND | 422 | A referenced depot ID does not exist. |
| JOB_ID_NOT_FOUND | 404 | The async job ID does not exist. |
| JOB_ALREADY_TERMINAL | 409 | Tried to cancel an async job that already completed/failed/was cancelled. |
| SOLVER_INFEASIBLE | 422 | The solver proved no feasible solution exists. |
| SOLVER_TIMEOUT_NO_SOLUTION | 422 | Time limit reached with no feasible solution found at all. |
| INTERNAL_ERROR | 500 | Unhandled internal error. |
| SOLVER_ERROR | 500 | Solver-level error. |
Example error response
{
"detail": {
"code": "VALIDATION_ERROR",
"message": "Resource 'truck-2' references depot 'base' which is not defined.",
"field": "resources[1].start_depot_id"
}
}
Recurring-jobs specific responses
The recurring-jobs router uses a plain HTTP exception with a string or dict detail rather than the full VRPError shape in some cases (e.g. 404 "Recurring job not found.", 409 duplicate external_id, 422 infeasible pattern). See the recurring-jobs endpoint reference for exact bodies.