openapi: 3.0.3
info:
  title: SOAT Errors
  version: 1.0.0
  description: >-
    The shape every error response carries. This file declares no paths: it
    exists so the envelope, the failure reason a resource records and a
    validation problem are each defined once rather than once per module.
  contact:
    name: SOAT Team
    url: https://github.com/ttoss/soat
paths: {}
components:
  responses:
    Unauthorized:
      description: Authentication required
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Forbidden:
      description: Insufficient permissions
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: 'FORBIDDEN'
              message: 'Forbidden'
              hint: >-
                The credential authenticated but is not allowed this action.
                Attach an IAM policy granting the action to the caller, or use a
                credential that has it.
              docs_url: 'https://soat.ttoss.dev/docs/error-codes#forbidden'
    NotFound:
      description: Not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  schemas:
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          description: >-
            Structured error. Every error response uses this shape — 401, 403
            and the 500 catch-all included — so `code` can be read without
            first checking the type of `error`.
          required:
            - code
            - message
            - hint
            - docs_url
          properties:
            code:
              type: string
              description: A key from the server's ERROR_CODES registry.
              example: RESOURCE_NOT_FOUND
            message:
              type: string
              example: 'Resource not found'
            hint:
              type: string
              description: >-
                What to do about this error. Resolved per code, so a caller that
                has never seen the code before can act on the response without
                leaving it.
              example: >-
                Check the id, and check that the credential can see the project
                that owns the resource.
            docs_url:
              type: string
              format: uri
              description: The reference-page anchor documenting this code.
              example: >-
                https://soat.ttoss.dev/docs/error-codes#resource_not_found
            meta:
              type: object
              description: Optional structured context for the error.
    StoredError:
      type: object
      description: >-
        Why a resource's work failed, in the shape of an error response's
        `error` without `hint` and `docs_url`. Every `error` field a resource
        records carries it, so `code` can be read without first checking the
        type of `error`.
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: >-
            A key from the server's ERROR_CODES registry, documented on the
            Error Codes page. `INTERNAL_ERROR`, with the message `Internal
            Server Error`, records an unexpected failure whose detail reaches
            the server log only.
          example: AI_PROVIDER_ERROR
        message:
          type: string
          example: 'Provider returned 402: insufficient credits'
        meta:
          type: object
          additionalProperties: true
          description: The failure's own structured context, when it names any.
    ValidationProblem:
      type: object
      description: >-
        One reason a definition was refused. A validation refusal lists every
        one under `meta.problems`, and a dry-run validate endpoint answers the
        same items.
      required:
        - code
        - path
        - message
      properties:
        code:
          type: string
          pattern: '^[A-Z][A-Z0-9_]*$'
          description: What kind of problem it is, stable across releases.
          example: MISSING_FIELD
        path:
          type: string
          description: Where in the request body the problem is.
          example: nodes[0].agent_id
        message:
          type: string
          description: The problem in words, naming the values involved.
          example: "agent node 'a' is missing required field 'agent_id'."
