Skip to content

Errors

All AFI errors are structured. Providers MUST NOT return unstructured error messages, bare HTTP status codes without a body, or free-form strings where an error object is expected.

Error shape

Error {
  code:         ErrorCode          // machine-readable, from the table below
  message:      string             // human-readable
  path?:        string             // the path being operated on, if applicable
  retry_after?: number             // seconds, present iff code == "rate_limited"
  [key: `x-${string}`]: any        // vendor extensions
}

ErrorCode =
  | "not_found"        // path does not exist, OR caller lacks access (see cloaking rule)
  | "invalid_path"     // path is malformed or escapes root
  | "unsupported"      // operation not in the manifest's capabilities
  | "rate_limited"     // provider throttling; retry_after MUST be set
  | "internal"         // provider bug or backing-store failure
  | "unauthorized"     // caller failed auth entirely (missing/invalid token)
  | "conflict"         // (Level 3 only) target already exists / concurrent mod

When to return which code

Situation Code
Client omits or presents invalid credentials on an auth-required provider unauthorized
Client is authenticated but lacks capability for the target path not_found (see cloaking)
Path syntactically invalid (\0, escapes root, exceeds max_length) invalid_path
Path syntactically valid but nothing exists there not_found
Client calls search on a Level 1 provider unsupported
Client calls write on a Level 2 provider unsupported
Backing store throws (DB error, disk full, network partition to backend) internal
Provider is throttling this client rate_limited
(Level 3) mkdir on an existing path conflict

Transport mapping

Providers MUST map error codes to transport-appropriate signaling and return the structured error body:

HTTP

Code HTTP status
not_found, invalid_path 404
unauthorized 401
unsupported 405
rate_limited 429 (MUST include Retry-After header)
conflict 409
internal 500

The response body is the structured Error as JSON with Content-Type: application/json.

MCP

Errors surface as MCP tool errors with the structured Error as the tool error payload. The tool call itself completes; MCP transport-level errors are reserved for actual transport failures.

FUSE

Codes map to errno values: not_foundENOENT, invalid_pathEINVAL, unsupportedENOSYS, unauthorizedEACCES, rate_limitedEAGAIN, conflictEEXIST, internalEIO.

SSH

Errors surface as bash-shaped stderr output plus a non-zero exit code. The stderr line SHOULD be prefixed afi: <path>: <code>: <message>.

Retries

Only rate_limited and (in some cases) internal are retriable. Clients SHOULD honor retry_after, use exponential backoff for internal, and NOT retry not_found, invalid_path, unsupported, or unauthorized.