can1357/oh-my-pi · error · AIError.ProviderResponseError
An unknown error occurred
Error message
An unknown error occurred
What it means
streamGoogleGeminiCli finished streaming a response whose output.stopReason was "aborted" or "error", and no provider error message was attached, so this generic fallback text is thrown as AIError.ProviderResponseError. It means the Gemini CLI endpoint signalled a failed/terminated response without explaining why.
Source
Thrown at packages/ai/src/providers/google-gemini-cli.ts:1104
break;
} catch (error) {
const status = extractHttpStatusFromError(error);
if (
!isLastEndpoint &&
!started &&
(AIError.isTransientStatus(status) ||
(status === undefined &&
!(error instanceof AIError.ProviderResponseError && error.kind === "output") &&
AIError.retriable(AIError.classify(error))))
) {
continue;
}
throw error;
}
}
if (output.stopReason === "aborted" || output.stopReason === "error") {
throw new AIError.ProviderResponseError(output.errorMessage ?? "An unknown error occurred", {
provider: model.provider,
kind: "output",
});
}
output.duration = performance.now() - startTime;
if (firstTokenTime) output.ttft = firstTokenTime - startTime;
stream.push({ type: "done", reason: output.stopReason, message: output });
stream.end();
} catch (error) {
const result = await AIError.finalize(error, { api: model.api, signal: options?.signal, rawRequestDump });
output.stopReason = result.stopReason;
output.errorStatus = result.status;
output.errorId = result.id;
output.errorMessage = result.message;
output.duration = performance.now() - startTime;
if (firstTokenTime) output.ttft = firstTokenTime - startTime;
stream.push({ type: "error", reason: output.stopReason, error: output });View on GitHub (pinned to 9690622007)
Solutions
- Log the full output object at the callsite to capture stopReason and any partial content before the throw
- Check Gemini CLI / Code Assist service status and auth token validity
- Retry the request — transient backend failures often produce empty error messages
- If aborts are user-driven, check options.signal before treating this as a provider failure
Example fix
// before
throw new AIError.ProviderResponseError(output.errorMessage ?? "An unknown error occurred", { provider: model.provider, kind: "output" });
// after
if (!output.errorMessage) {
logger.error("gemini-cli opaque error", { stopReason: output.stopReason, provider: model.provider });
}
throw new AIError.ProviderResponseError(output.errorMessage ?? `Gemini CLI stream ended with stopReason=${output.stopReason}`, { provider: model.provider, kind: "output" }); Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
null
Try / catch
try {
await streamGoogleGeminiCli(model, params, { signal });
} catch (err) {
if (err instanceof AIError.AbortError) throw err; // rethrow user aborts
if (err instanceof AIError.ProviderResponseError && err.context?.kind === "output") {
logger.warn("gemini-cli ended without error message", { message: err.message });
return retryWithBackoff();
}
throw err;
} Prevention
- Always pass an AbortSignal and check signal.aborted before interpreting failures as provider errors
- Attach an onError/message handler that captures error chunks into output.errorMessage so the fallback text is less likely
- Add retry with backoff around Gemini CLI streams
- Monitor Google Code Assist service status
When it happens
Trigger: The aggregated stream output has stopReason "error" or "aborted" but output.errorMessage is null/undefined — e.g. the Gemini CLI backend emitted a terminal chunk with an error stop reason and no message.
Common situations: Gemini Code Assist / CLI backend outages returning opaque error terminations; quota or safety terminations that omit a message; aborted generations surfaced as stop reasons rather than exceptions.
Related errors
- Devin Connect frame length ${len} exceeds ${MAX_CONNECT_FRAM
- Request blocked by Google (${chunk.promptFeedback.blockReaso
- Google API stream ended without a finish reason (connection
- An unknown error occurred
- Google API returned an empty response body
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/dab1acc8e8028f2d.
Report an issue: GitHub.