{
  "topic": "errors",
  "path": [
    "errors"
  ],
  "title": "cyoda error reference",
  "synopsis": "Every error response from the Cyoda REST API carries a structured `errorCode` in the `properties` object. Multiple codes may share the same HTTP status. Programmatic handling keys on `errorCode`, not HTTP status.",
  "body": "# errors\n\n## NAME\n\nerrors — error model and code catalogue.\n\n## SYNOPSIS\n\nREST responses use RFC 9457 Problem Details:\n\n```json\n{\n  \"type\": \"about:blank\",\n  \"title\": \"Not Found\",\n  \"status\": 404,\n  \"detail\": \"ENTITY_NOT_FOUND: entity id=abc not found\",\n  \"instance\": \"/api/v1/entities/abc\",\n  \"properties\": {\n    \"errorCode\": \"ENTITY_NOT_FOUND\",\n    \"retryable\": false\n  }\n}\n```\n\ngRPC error envelope example (returned in the CloudEvent response payload):\n\n```json\n{\n  \"error\": {\n    \"code\": \"ENTITY_NOT_FOUND\",\n    \"message\": \"entity id=abc not found\",\n    \"retryable\": false\n  }\n}\n```\n\nThe gRPC response also carries `errorCode` and `retryable` in trailer metadata.\n\n## DESCRIPTION\n\nEvery error response from the Cyoda REST API carries a structured `errorCode` in the `properties` object. Multiple codes may share the same HTTP status. Programmatic handling keys on `errorCode`, not HTTP status.\n\nThe `retryable` property is present and `true` only when the operation is safe to retry as-is (e.g., transient cluster conditions). When absent or `false`, the request or system state must change before retrying.\n\n5xx responses include a `ticket` UUID for server-side log correlation. Share this value when reporting issues.\n\n`CYODA_ERROR_RESPONSE_MODE` controls 5xx detail level. `sanitized` (default): generic message plus `ticket` UUID. `verbose`: internal error detail included in the response body; intended for development environments only.\n\n## ERROR CODE INDEX\n\n- `errors.BAD_REQUEST` — `400` — not retryable — request body, query parameter, or header is malformed or structurally invalid\n- `errors.CLUSTER_NODE_NOT_REGISTERED` — `503` — retryable — target cluster node is not present in the gossip registry\n- `errors.COMPUTE_MEMBER_DISCONNECTED` — `503` — retryable — compute member holding a processor assignment has disconnected\n- `errors.CONFLICT` — `409` — retryable — optimistic concurrency check failed; entity was modified concurrently\n- `errors.DISPATCH_FORWARD_FAILED` — `503` — retryable — HTTP forwarding call to peer node failed\n- `errors.DISPATCH_TIMEOUT` — `503` — retryable (see note) — compute member did not respond within the dispatch timeout; completion on the remote node is not guaranteed\n- `errors.ENTITY_NOT_FOUND` — `404` — not retryable — entity UUID does not exist or is not accessible to the caller\n- `errors.EPOCH_MISMATCH` — `409` — retryable — writing node's cached shard epoch is stale; another node has since taken ownership\n- `errors.FORBIDDEN` — `403` — not retryable — authenticated caller lacks the required role or the tenant does not match\n- `errors.HELP_TOPIC_NOT_FOUND` — `404` — not retryable — help topic path does not resolve to any topic in the tree\n- `errors.IDEMPOTENCY_CONFLICT` — `409` — not retryable — request with the same idempotency key was received but payload differs from the original\n- `errors.MODEL_NOT_FOUND` — `404` — not retryable — referenced entity model does not exist in the tenant's model registry\n- `errors.MODEL_NOT_LOCKED` — `409` — not retryable — model exists but is not in `LOCKED` state; entity writes require a locked model\n- `errors.NO_COMPUTE_MEMBER_FOR_TAG` — `503` — retryable — no live cluster node advertises the compute tag required by the processor\n- `errors.NOT_IMPLEMENTED` — `501` — not retryable — endpoint is defined but has no functional implementation in this version\n- `errors.POLYMORPHIC_SLOT` — `400` — not retryable — payload discriminator selects an unrecognised variant or fails the variant schema\n- `errors.SEARCH_JOB_ALREADY_TERMINAL` — `409` — not retryable — operation attempted on a search job that has already completed, failed, or been cancelled\n- `errors.SEARCH_JOB_NOT_FOUND` — `404` — not retryable — referenced search job does not exist in the current tenant\n- `errors.SEARCH_RESULT_LIMIT` — `400` — not retryable — search query matched more results than the server-enforced maximum\n- `errors.SEARCH_SHARD_TIMEOUT` — `503` — retryable — one or more search shards did not respond within the configured timeout\n- `errors.SERVER_ERROR` — `500` — retryable with caution — unclassified internal error; response includes `ticket` UUID for log correlation\n- `errors.TRANSACTION_EXPIRED` — `400` — not retryable — transaction token's `exp` claim is in the past\n- `errors.TRANSACTION_NODE_UNAVAILABLE` — `503` — retryable — cluster node that owns the open transaction is unreachable\n- `errors.TRANSACTION_NOT_FOUND` — `404` — not retryable — transaction ID does not correspond to an active transaction on this node\n- `errors.TRANSITION_NOT_FOUND` — `404` — not retryable — requested workflow transition is not defined for the entity's current state\n- `errors.TX_CONFLICT` — `409` — retryable — transaction aborted due to storage-level serialization conflict\n- `errors.TX_COORDINATOR_NOT_CONFIGURED` — `503` — not retryable — distributed transaction coordinator is disabled or misconfigured on this node\n- `errors.TX_NO_STATE` — `404` — not retryable — coordinator has no state record for the given transaction ID\n- `errors.TX_REQUIRED` — `400` — not retryable — operation requires a transaction context but none was provided\n- `errors.UNAUTHORIZED` — `401` — not retryable — `Authorization` header is missing, token is expired, signature is invalid, or issuer is untrusted\n- `errors.VALIDATION_FAILED` — `400` — not retryable — payload is structurally valid JSON but fails the model's schema or workflow validation rules\n- `errors.WORKFLOW_FAILED` — `400` — not retryable — workflow processor or guard condition returned a failure during state transition\n- `errors.WORKFLOW_NOT_FOUND` — `404` — not retryable — workflow definition referenced by the entity model does not exist\n\n## SEE ALSO\n\n- openapi\n- grpc\n- config\n",
  "sections": [
    {
      "name": "NAME",
      "body": "errors — error model and code catalogue."
    },
    {
      "name": "SYNOPSIS",
      "body": "REST responses use RFC 9457 Problem Details:\n\n```json\n{\n  \"type\": \"about:blank\",\n  \"title\": \"Not Found\",\n  \"status\": 404,\n  \"detail\": \"ENTITY_NOT_FOUND: entity id=abc not found\",\n  \"instance\": \"/api/v1/entities/abc\",\n  \"properties\": {\n    \"errorCode\": \"ENTITY_NOT_FOUND\",\n    \"retryable\": false\n  }\n}\n```\n\ngRPC error envelope example (returned in the CloudEvent response payload):\n\n```json\n{\n  \"error\": {\n    \"code\": \"ENTITY_NOT_FOUND\",\n    \"message\": \"entity id=abc not found\",\n    \"retryable\": false\n  }\n}\n```\n\nThe gRPC response also carries `errorCode` and `retryable` in trailer metadata."
    },
    {
      "name": "DESCRIPTION",
      "body": "Every error response from the Cyoda REST API carries a structured `errorCode` in the `properties` object. Multiple codes may share the same HTTP status. Programmatic handling keys on `errorCode`, not HTTP status.\n\nThe `retryable` property is present and `true` only when the operation is safe to retry as-is (e.g., transient cluster conditions). When absent or `false`, the request or system state must change before retrying.\n\n5xx responses include a `ticket` UUID for server-side log correlation. Share this value when reporting issues.\n\n`CYODA_ERROR_RESPONSE_MODE` controls 5xx detail level. `sanitized` (default): generic message plus `ticket` UUID. `verbose`: internal error detail included in the response body; intended for development environments only."
    },
    {
      "name": "ERROR CODE INDEX",
      "body": "- `errors.BAD_REQUEST` — `400` — not retryable — request body, query parameter, or header is malformed or structurally invalid\n- `errors.CLUSTER_NODE_NOT_REGISTERED` — `503` — retryable — target cluster node is not present in the gossip registry\n- `errors.COMPUTE_MEMBER_DISCONNECTED` — `503` — retryable — compute member holding a processor assignment has disconnected\n- `errors.CONFLICT` — `409` — retryable — optimistic concurrency check failed; entity was modified concurrently\n- `errors.DISPATCH_FORWARD_FAILED` — `503` — retryable — HTTP forwarding call to peer node failed\n- `errors.DISPATCH_TIMEOUT` — `503` — retryable (see note) — compute member did not respond within the dispatch timeout; completion on the remote node is not guaranteed\n- `errors.ENTITY_NOT_FOUND` — `404` — not retryable — entity UUID does not exist or is not accessible to the caller\n- `errors.EPOCH_MISMATCH` — `409` — retryable — writing node's cached shard epoch is stale; another node has since taken ownership\n- `errors.FORBIDDEN` — `403` — not retryable — authenticated caller lacks the required role or the tenant does not match\n- `errors.HELP_TOPIC_NOT_FOUND` — `404` — not retryable — help topic path does not resolve to any topic in the tree\n- `errors.IDEMPOTENCY_CONFLICT` — `409` — not retryable — request with the same idempotency key was received but payload differs from the original\n- `errors.MODEL_NOT_FOUND` — `404` — not retryable — referenced entity model does not exist in the tenant's model registry\n- `errors.MODEL_NOT_LOCKED` — `409` — not retryable — model exists but is not in `LOCKED` state; entity writes require a locked model\n- `errors.NO_COMPUTE_MEMBER_FOR_TAG` — `503` — retryable — no live cluster node advertises the compute tag required by the processor\n- `errors.NOT_IMPLEMENTED` — `501` — not retryable — endpoint is defined but has no functional implementation in this version\n- `errors.POLYMORPHIC_SLOT` — `400` — not retryable — payload discriminator selects an unrecognised variant or fails the variant schema\n- `errors.SEARCH_JOB_ALREADY_TERMINAL` — `409` — not retryable — operation attempted on a search job that has already completed, failed, or been cancelled\n- `errors.SEARCH_JOB_NOT_FOUND` — `404` — not retryable — referenced search job does not exist in the current tenant\n- `errors.SEARCH_RESULT_LIMIT` — `400` — not retryable — search query matched more results than the server-enforced maximum\n- `errors.SEARCH_SHARD_TIMEOUT` — `503` — retryable — one or more search shards did not respond within the configured timeout\n- `errors.SERVER_ERROR` — `500` — retryable with caution — unclassified internal error; response includes `ticket` UUID for log correlation\n- `errors.TRANSACTION_EXPIRED` — `400` — not retryable — transaction token's `exp` claim is in the past\n- `errors.TRANSACTION_NODE_UNAVAILABLE` — `503` — retryable — cluster node that owns the open transaction is unreachable\n- `errors.TRANSACTION_NOT_FOUND` — `404` — not retryable — transaction ID does not correspond to an active transaction on this node\n- `errors.TRANSITION_NOT_FOUND` — `404` — not retryable — requested workflow transition is not defined for the entity's current state\n- `errors.TX_CONFLICT` — `409` — retryable — transaction aborted due to storage-level serialization conflict\n- `errors.TX_COORDINATOR_NOT_CONFIGURED` — `503` — not retryable — distributed transaction coordinator is disabled or misconfigured on this node\n- `errors.TX_NO_STATE` — `404` — not retryable — coordinator has no state record for the given transaction ID\n- `errors.TX_REQUIRED` — `400` — not retryable — operation requires a transaction context but none was provided\n- `errors.UNAUTHORIZED` — `401` — not retryable — `Authorization` header is missing, token is expired, signature is invalid, or issuer is untrusted\n- `errors.VALIDATION_FAILED` — `400` — not retryable — payload is structurally valid JSON but fails the model's schema or workflow validation rules\n- `errors.WORKFLOW_FAILED` — `400` — not retryable — workflow processor or guard condition returned a failure during state transition\n- `errors.WORKFLOW_NOT_FOUND` — `404` — not retryable — workflow definition referenced by the entity model does not exist"
    },
    {
      "name": "SEE ALSO",
      "body": "- openapi\n- grpc\n- config"
    }
  ],
  "see_also": [
    "openapi",
    "grpc",
    "config"
  ],
  "stability": "stable",
  "actions": [],
  "children": [
    "errors.BAD_REQUEST",
    "errors.CLUSTER_NODE_NOT_REGISTERED",
    "errors.COMPUTE_MEMBER_DISCONNECTED",
    "errors.CONFLICT",
    "errors.DISPATCH_FORWARD_FAILED",
    "errors.DISPATCH_TIMEOUT",
    "errors.ENTITY_NOT_FOUND",
    "errors.EPOCH_MISMATCH",
    "errors.FORBIDDEN",
    "errors.HELP_TOPIC_NOT_FOUND",
    "errors.IDEMPOTENCY_CONFLICT",
    "errors.MODEL_NOT_FOUND",
    "errors.MODEL_NOT_LOCKED",
    "errors.NOT_IMPLEMENTED",
    "errors.NO_COMPUTE_MEMBER_FOR_TAG",
    "errors.POLYMORPHIC_SLOT",
    "errors.SEARCH_JOB_ALREADY_TERMINAL",
    "errors.SEARCH_JOB_NOT_FOUND",
    "errors.SEARCH_RESULT_LIMIT",
    "errors.SEARCH_SHARD_TIMEOUT",
    "errors.SERVER_ERROR",
    "errors.TRANSACTION_EXPIRED",
    "errors.TRANSACTION_NODE_UNAVAILABLE",
    "errors.TRANSACTION_NOT_FOUND",
    "errors.TRANSITION_NOT_FOUND",
    "errors.TX_CONFLICT",
    "errors.TX_COORDINATOR_NOT_CONFIGURED",
    "errors.TX_NO_STATE",
    "errors.TX_REQUIRED",
    "errors.UNAUTHORIZED",
    "errors.VALIDATION_FAILED",
    "errors.WORKFLOW_FAILED",
    "errors.WORKFLOW_NOT_FOUND"
  ]
}
