Skip to content

Design extensible Session error details #35325

Description

@kitlangton

Context

#35272 intentionally keeps the public Session error wire contract minimal and forward-compatible:

type SessionError = {
  type: string
  message: string
}

Core may classify failures more precisely internally, but internal provider, permission, and tool fields should not become permanent public commitments without demonstrated consumers and an explicit compatibility model.

Goal

Design the next public Session error model, if richer machine-readable details are justified, without requiring database resets or breaking older SDK clients when new error classifications or fields are introduced.

Investigation

  1. Inventory concrete consumer needs across the TUI, App, SDK users, automation, telemetry, retries, authentication recovery, permission display, and tool diagnostics.
  2. Audit established error contracts and document the tradeoffs behind them:
    • RFC 9457 Problem Details
    • JSON:API error objects
    • Stripe and GitHub REST errors
    • GraphQL errors and extensions
    • gRPC Status and typed details
    • OpenAI and other relevant model-provider APIs
  3. Compare at least these candidate shapes with ideal consumer call sites:
    • Minimal open { type, message }
    • Open envelope plus optional JSON details or data
    • Stable coarse category plus open type
    • Known typed details layered over an open wire envelope
    • Versioned rich error contracts
  4. Pressure-test unknown future types, malformed known details, persisted historical events, mixed-version clients, generated SDK ergonomics, and whether a generic field bag becomes an ungoverned junk drawer.
  5. Separate internal failure algebras from the public transport contract and identify which information belongs in logs, events, dedicated fields, or error details.

Compatibility Laws

  • Older clients must accept newly introduced error type values.
  • Unknown types must remain renderable through message.
  • New optional fields must not make historical durable events undecodable.
  • No required per-type field may be added without an explicit versioning and migration decision.
  • Retry policy must not depend on public error details unless that behavior is deliberately part of the contract.
  • Public type values must not be renamed or repurposed after release.

Deliverables

  • A survey table of analogous APIs and the constraints each design addresses.
  • An inventory of actual OpenCode consumer requirements.
  • Two or three candidate wire contracts with generated TypeScript examples and fallback handling.
  • A recommended contract, naming rationale (type, code, name, details, or data), and compatibility laws.
  • A persistence/versioning decision and migration analysis.
  • Focused schema and mixed-version compatibility tests for the selected design.

Non-goals

  • Do not expose the current internal error union merely because it already exists.
  • Do not add a generic details bag until at least one concrete consumer and governance rule justify it.
  • Do not change retry semantics as part of the error-shape design.

Metadata

Metadata

Assignees

No one assigned

    Labels

    2.0coreAnything pertaining to core functionality of the application (opencode server stuff)discussionUsed for feature requests, proposals, ideas, etc. Open discussiongang-grillDesign topics queued for later group grilling

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions