Repository navigation
fix(runtime): derive provider error reason and message from one classification #1074
Description
Problem
A structured provider stream failure can be classified correctly by the runtime while still producing the generic visible message Operation failed.
Observed in a Maka CLI session using Ollama Cloud with GLM-5.2:
- Four runs ended with
failureClass: "network". - All four persisted
failureMessage: "Operation failed". - The CLI faithfully rendered the runtime error event; the actionable category had already been lost before reaching the CLI projection.
This produces a contradictory error projection:
reason: network
message: Operation failed
Root cause
ModelAdapter.makeErrorEvent() currently derives the machine-readable reason and user-visible message through different paths:
const message = generalizedErrorMessage(err);
const reason = errorReasonFromClass(classifyError(err));classifyError() normalizes structured provider error objects and serializes their nested evidence, so an object containing fetch or network is correctly classified as Network.
generalizedErrorMessage() uses String(error) for non-Error values. A structured provider object therefore becomes [object Object], misses every category, and falls back to Operation failed.
The provider classification is already the authoritative fact. The visible message should be derived from that same classification rather than independently parsing the raw value again.
Desired outcome
A provider error is classified once at the runtime boundary, and both its machine-readable reason and safe user-visible message are derived from that classification.
For a structured network error, the emitted event must contain:
reason: network
message: Network error
Proposed seam
- Add a pure safe-message mapping next to the existing provider error classification helpers.
- In
ModelAdapter.makeErrorEvent(), callclassifyError()once. - Derive both
reasonandmessagefrom the resulting class. - Stop using
generalizedErrorMessage()for provider error events. - Keep generic UI error handling unchanged.
If a second caller later needs the complete class/reason/message/code projection, the helpers can be combined into a first-class projectProviderError() API then. This issue does not require that broader abstraction.
Acceptance criteria
- A structured provider object containing network evidence emits:
reason: "network"message: "Network error"
reasonandmessagecannot describe different provider error categories.- Existing
Errorand string provider inputs retain their safe categorized messages. - Raw provider messages and secrets are not exposed in visible events.
- Unknown provider errors still fall back to
Operation failed. - Unit tests cover structured object,
Error, and string inputs.
Non-goals
- Changing retry policy.
- Retrying after partial model output.
- Adding attempt supersession semantics.
- Exposing raw provider error bodies.
- Refactoring generic Desktop/UI error presentation.
- Migrating telemetry and trace APIs to a new projection type.
Activity