Skip to content

Provider stream truncation (finishReason="other" with zero output) silently accepted, persisting half-finished assistant messages #26170

Description

@edevil

Bug

When an upstream provider stream is cut mid-generation, the AI SDK emits
a fallback finishReason: "other" with zero output tokens. opencode's
session processor accepts this as a normal end-of-step, persists a
truncated assistant message, and continues — no error, no retry, no
recovery indicator.

Symptom

The session stores a half-finished message and the user gets a partial
response with no warning. Users typically respond by manually
re-prompting, get a few good turns, then hit the bug again — the
"session degradation" pattern reported in #16214.

Trigger

{ type: "text-delta", delta: "..." }
{ type: "text-delta", delta: "..." }   ← upstream stream cuts here
{ type: "finish", finishReason: "other", usage: { outputTokens: 0 } }
                                                 ↑
                       AI SDK's "no stop reason was given" fallback

The session processor sees finish-step with
finishReason === "other" and usage.tokens.output === 0.

Real-world evidence

I found more than a dozen instances of this exact pattern in my own
opencode session database, spanning two providers (anthropic, openai)
and four models (gpt-5.3-codex, claude-opus-4-6, claude-opus-4-7,
claude-haiku-4-5). All exhibit the shape:

{
  "role": "assistant",
  "finish": "other",
  "tokens": { "input": 0, "output": 0, "reasoning": 0, "cache": {...} },
  "cost": 0
}

In one diagnostic example the reasoning text literally ends mid-word
("...whichlang::detect_language() functi"), proving the upstream stream
was severed before the next chunk arrived — this is not a model decision
to stop.

Why this is distinct from related reports

Suggested fix

Detect finishReason === "other" && tokens.output === 0 at the session
processor layer (covers all AI-SDK providers), surface as a retryable
APIError, cap retries at a small number to avoid loops on persistently
misbehaving providers.

Environment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions