{"record":{"id":"16972b490f964bf8","repo":"google-gemini/gemini-cli","slug":"invalid-stream","errorCode":"INVALID_STREAM","errorMessage":"${event.value?.message?.trim() || 'Invalid stream received from model'}","messagePattern":"\\$\\{event\\.value\\?\\.message\\?\\.trim\\(\\) \\|\\| 'Invalid stream received from model'\\}","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/core/src/agent/event-translator.ts","lineNumber":230,"sourceCode":"          status: 'PERMISSION_DENIED',\n          message: event.value.systemMessage?.trim() || event.value.reason,\n          fatal: false,\n          _meta: { code: 'AGENT_EXECUTION_BLOCKED' },\n        }),\n      );\n      break;\n\n    case GeminiEventType.InvalidStream:\n      ensureStreamStart(state, out);\n      out.push(\n        makeEvent('error', state, {\n          status: 'INTERNAL',\n          message:\n            event.value?.message?.trim() ||\n            'Invalid stream received from model',\n          fatal: true,\n          _meta: {\n            code: 'INVALID_STREAM',\n            errorType: event.value?.type,\n            rawMessage: event.value?.message,\n          },\n        }),\n      );\n      break;\n\n    case GeminiEventType.ToolCallRequest:\n      ensureStreamStart(state, out);\n      state.pendingToolNames.set(event.value.callId, event.value.name);\n      out.push(\n        makeEvent('tool_request', state, {\n          requestId: event.value.callId,\n          name: event.value.name,\n          args: event.value.args,\n          display: event.value.display,\n        }),\n      );","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/core/src/agent/event-translator.ts#L212-L248","documentation":"INVALID_STREAM is emitted as a FATAL INTERNAL error when the model returns a stream chunk that cannot be parsed (GeminiEventType.InvalidStream). legacy-agent-session treats it as terminal (_finishStream('failed')). The message is the trimmed upstream message or 'Invalid stream received from model'.","triggerScenarios":"sendMessageStream yields GeminiEventType.InvalidStream with optional {message,type} -> translateEvent pushes makeEvent('error', { status:'INTERNAL', fatal:true, _meta.code:'INVALID_STREAM', errorType, rawMessage }).","commonSituations":"Model/API version mismatch returning an unknown part type; truncated response from a network blip; proxy or load balancer corrupting the SSE stream; using a preview model that emits unsupported fields.","solutions":["Retry once on a fresh session — most INVALID_STREAM events are transient.","Pin to a stable model version and verify the SDK version matches the API contract.","Inspect _meta.rawMessage / errorType to identify the unparseable part, then report or filter it.","If behind a proxy, bypass it to confirm the stream is intact end-to-end."],"exampleFix":"// before\nconst model = 'gemini-3-pro-preview';\n// after\nconst model = 'gemini-3-pro';  // stable GA version","handlingStrategy":"retry","validationCode":"// verify model/sdk compatibility before opening the stream\nif (!isSupportedModelPairing(config.getActiveModel(), sdkVersion)) {\n  throw new Error('Unsupported model for this SDK version');\n}","typeGuard":"function isInvalidStream(ev: unknown): boolean {\n  return typeof ev === 'object' && ev !== null && (ev as any)._meta?.code === 'INVALID_STREAM';\n}","tryCatchPattern":"// fatal: the session ends. Retry once on a fresh session.\nfor await (const ev of session) {\n  if (ev.type === 'error' && ev._meta?.code === 'INVALID_STREAM') {\n    return retryOnceWithFreshSession();\n  }\n}","preventionTips":["Pin model and SDK versions that are tested together.","Bypass streaming proxies that can corrupt SSE when diagnosing."],"tags":["model-stream","fatal","gemini","typescript"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}