can1357/oh-my-pi · error · AIError.ProviderResponseError
An unknown error occurred
Error message
An unknown error occurred
What it means
consumeGoogleStream completed with output.stopReason "aborted" or "error" and output.errorMessage was not populated, so this generic fallback text is thrown as AIError.ProviderResponseError (kind "output"). The Google stream signalled a failed terminal state without a reason string.
Source
Thrown at packages/ai/src/providers/google-shared.ts:774
calculateCost(model, output.usage);
}
}
flushCurrent();
if (options?.signal?.aborted) {
throw new AIError.AbortError();
}
if (!sawFinishReason) {
throw new AIError.ProviderResponseError(
"Google API stream ended without a finish reason (connection dropped or response truncated)",
{ provider: model.provider, kind: "incomplete-stream" },
);
}
if (output.stopReason === "aborted" || output.stopReason === "error") {
throw new AIError.ProviderResponseError(output.errorMessage ?? "An unknown error occurred", {
provider: model.provider,
kind: "output",
});
}
}
/**
* Generation/sampling fields that map directly onto Gemini's `GenerateContentConfig`.
* Excludes any provider-specific extensions (`topP`/`topK`/etc are all forwarded as-is).
*/
interface GoogleGenerationConfig extends GenerateContentConfig {
topP?: number;
topK?: number;
minP?: number;
presencePenalty?: number;
repetitionPenalty?: number;
}
View on GitHub (pinned to 9690622007)
Solutions
- If stopReason is "aborted", verify options.signal — this may be an intentional user abort, handle it as AbortError instead of a provider failure
- Capture partial output/accumulated chunks before the throw to diagnose what the model produced
- Retry on "error" stop reasons like MALFORMED_FUNCTION_CALL; reduce or fix tool schemas to avoid malformed calls
- Check Google service status for backend incidents
Example fix
// before
if (output.stopReason === "aborted" || output.stopReason === "error") {
throw new AIError.ProviderResponseError(output.errorMessage ?? "An unknown error occurred", { provider: model.provider, kind: "output" });
}
// after
if (output.stopReason === "aborted" || output.stopReason === "error") {
throw new AIError.ProviderResponseError(
output.errorMessage ?? `Google stream ended with stopReason=${output.stopReason}`,
{ provider: model.provider, kind: "output" },
);
} Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
function isAbortOrErrorStop(o: { stopReason: string }): boolean {
return o.stopReason === "aborted" || o.stopReason === "error";
} Try / catch
try {
await streamGoogle(model, params, { signal });
} catch (err) {
if (err instanceof AIError.AbortError || signal.aborted) throw err; // user-intent abort
if (err instanceof AIError.ProviderResponseError && err.context?.kind === "output" && err.message === "An unknown error occurred") {
logger.warn("google stream failed without message; retrying", {});
return withBackoff(() => streamGoogle(model, params, { signal }));
}
throw err;
} Prevention
- Check signal.aborted first so intentional aborts aren't mistaken for provider failures
- Validate/normalize tool schemas (JSON Schema) to reduce MALFORMED_FUNCTION_CALL terminations
- Keep accumulated partial text so a failed stream still yields usable content
- Retry with backoff on unexplained error stop reasons
When it happens
Trigger: Final chunk carries finishReason mapping to "error" (e.g. MALFORMED_FUNCTION_CALL, LANGUAGE, UNEXPECTED_TOOL_CALL, NO_IMAGE) or "aborted" (user abort via signal), and errorMessage was never set from prior error chunks.
Common situations: Model emits a malformed function call that Google terminates with MALFORMED_FUNCTION_CALL; user aborts mid-generation (check signal first); Google internal error terminations with no message.
Related errors
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/50beea8a718dc33a.
Report an issue: GitHub.