{"record":{"id":"dab1acc8e8028f2d","repo":"can1357/oh-my-pi","slug":"an-unknown-error-occurred-dab1ac","errorCode":null,"errorMessage":"An unknown error occurred","messagePattern":"An unknown error occurred","errorType":"exception","errorClass":"AIError.ProviderResponseError","httpStatus":null,"severity":"error","filePath":"packages/ai/src/providers/google-gemini-cli.ts","lineNumber":1104,"sourceCode":"\t\t\t\t\tbreak;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst status = extractHttpStatusFromError(error);\n\t\t\t\t\tif (\n\t\t\t\t\t\t!isLastEndpoint &&\n\t\t\t\t\t\t!started &&\n\t\t\t\t\t\t(AIError.isTransientStatus(status) ||\n\t\t\t\t\t\t\t(status === undefined &&\n\t\t\t\t\t\t\t\t!(error instanceof AIError.ProviderResponseError && error.kind === \"output\") &&\n\t\t\t\t\t\t\t\tAIError.retriable(AIError.classify(error))))\n\t\t\t\t\t) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (output.stopReason === \"aborted\" || output.stopReason === \"error\") {\n\t\t\t\tthrow new AIError.ProviderResponseError(output.errorMessage ?? \"An unknown error occurred\", {\n\t\t\t\t\tprovider: model.provider,\n\t\t\t\t\tkind: \"output\",\n\t\t\t\t});\n\t\t\t}\n\n\t\t\toutput.duration = performance.now() - startTime;\n\t\t\tif (firstTokenTime) output.ttft = firstTokenTime - startTime;\n\t\t\tstream.push({ type: \"done\", reason: output.stopReason, message: output });\n\t\t\tstream.end();\n\t\t} catch (error) {\n\t\t\tconst result = await AIError.finalize(error, { api: model.api, signal: options?.signal, rawRequestDump });\n\t\t\toutput.stopReason = result.stopReason;\n\t\t\toutput.errorStatus = result.status;\n\t\t\toutput.errorId = result.id;\n\t\t\toutput.errorMessage = result.message;\n\t\t\toutput.duration = performance.now() - startTime;\n\t\t\tif (firstTokenTime) output.ttft = firstTokenTime - startTime;\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });","sourceCodeStart":1086,"sourceCodeEnd":1122,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/ai/src/providers/google-gemini-cli.ts#L1086-L1122","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nthrow new AIError.ProviderResponseError(output.errorMessage ?? \"An unknown error occurred\", { provider: model.provider, kind: \"output\" });\n// after\nif (!output.errorMessage) {\n  logger.error(\"gemini-cli opaque error\", { stopReason: output.stopReason, provider: model.provider });\n}\nthrow new AIError.ProviderResponseError(output.errorMessage ?? `Gemini CLI stream ended with stopReason=${output.stopReason}`, { provider: model.provider, kind: \"output\" });","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n  await streamGoogleGeminiCli(model, params, { signal });\n} catch (err) {\n  if (err instanceof AIError.AbortError) throw err; // rethrow user aborts\n  if (err instanceof AIError.ProviderResponseError && err.context?.kind === \"output\") {\n    logger.warn(\"gemini-cli ended without error message\", { message: err.message });\n    return retryWithBackoff();\n  }\n  throw err;\n}","preventionTips":["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"],"tags":["google","gemini-cli","streaming","provider-response"],"backgroundTag":"opaque-provider-error","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}