fix(summarizer): raise on stream failure instead of swallowing it as an empty summary#324
Merged
Conversation
…an empty summary A failed summary stream (Ollama 404, cloud API error, adapter error record) was logged and then swallowed (bare return), so consumers saw an empty-but-successful stream and wrote an empty note + STREAM_COMPLETE + exit 0 with no error surfaced anywhere. The whole downstream error path (STREAM_ERROR + exit 1 in simple_recorder, failure mapping in app/main.js) already existed - the generators just never raised into it. - _stream_completion: all four provider paths (anthropic/bedrock/openai/ ollama) now log + raise the original exception - _adapter_stream: error NDJSON record, HTTPError, and transport errors now raise (query_transcript_streaming catches and shows them inline) - summarize_transcript_streaming: empty-stream guard - a stream that completes without raising but yields no non-whitespace content raises ValueError instead of saving an empty summary (mirrors the existing map-reduce empty-reduce guard) - tests: unit coverage for all provider paths + empty-stream guard; model-free t2 e2e (summarize-failure) drives reprocess against a mock Ollama 404 and asserts honest failure + the existing summary untouched Fixes ruzin#301
ruzin
approved these changes
Jul 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When a summary stream fails (Ollama returning 404 "model not found", a cloud API error, or an adapter error record), the failure was swallowed and reported as success: the user got an empty note ("No summary available for this meeting") with no error surfaced anywhere. Reproduced end-to-end against a real meeting with a broken Ollama: the backend logged
ERROR - Ollama streaming failed: ... 404but still printedSTREAM_COMPLETE+Summary reprocessed successfullyand exited 0.Root cause: the streaming generators in
src/summarizer.pylogged provider errors and then ended the generator silently (logger.error(...); return). Everything downstream was already correct - all five consumer sites insimple_recorder.pycatch generator exceptions and emitSTREAM_ERROR+ exit 1, andapp/main.jsmaps that to failure events. The generators just never raised into that path. This is also the root cause of #301 (cloud streaming failures swallowed).Fix
src/summarizer.pyonly - no consumer changes needed:_stream_completion: all four provider paths (Anthropic, Bedrock, OpenAI-compatible, Ollama) now log and re-raise the original exception, so the real message (e.g.model 'x' not found (404)) reaches the UI viaSTREAM_ERROR._adapter_stream: an NDJSON error record, an HTTPError, and transport errors now raise after logging. Its second consumer (query_transcript_streaming, the chat path) already catches provider errors and yields a visible[Error: ...]chunk, so chat via the adapter now shows the error instead of an empty answer.summarize_transcript_streaming: defense-in-depth empty-stream guard - a stream that completes without raising but yields no non-whitespace content raisesValueErrorinstead of saving an empty summary. Mirrors the existing empty-reduce guard in_map_reduce_streaming.A failed regenerate can no longer clobber an existing good summary: the consumers exit before the write.
Tests
tests/test_summarizer_stream_errors.py, 11 tests, written first and failing before the fix): error propagation for the Ollama, Anthropic, Bedrock, OpenAI-compatible and adapter paths (error record / HTTPError / transport), the empty-stream guard (plain + template path), and a success-passthrough regression guard.e2e/specs/summarize-failure.t2.spec.ts): drives a realreprocessagainst a mock Ollama answering/api/chatwith the real 404 shape (new opt-inchatErroroption inmock-ollama.js, default off - existing specs unaffected) and asserts the operation reportssuccess:falseand the pre-existing summary on disk stays byte-for-byte unchanged.summarize-contracte2e re-run green (mock change is non-breaking), backend bundle rebuilt before the e2e run so the spec proves the fix end-to-end.Fixes #301
Summary by cubic
Surface real errors from summary streaming and stop saving empty notes. Failures (e.g., Ollama 404, cloud API, adapter errors) now trigger
STREAM_ERRORand never overwrite a good summary.STREAM_ERROR.{"type":"error"},HTTPError, and transport errors; chat path shows an inline[Error: ...]chunk.ValueErrorinstead of saving an empty summary.Written for commit 49e73b4. Summary will update on new commits.