Skip to content

Commit 43e5103

Browse files
committed
🤖 Add defensive checks for init-output and message processing
Fixes two issues found after PR #228: 1. **Init-output undefined line crash**: Added null check for data.line before calling trimEnd(). Prevents crash when init-output events arrive with missing line data during replay or out-of-order scenarios. 2. **Message processing condition tightened**: Added 'role' field check to ensure only CmuxMessages are processed in the caught-up branch. This makes the condition symmetric with the buffering branch and ensures we don't accidentally process malformed messages. Both changes follow the defensive programming pattern established in PR #228 - gracefully handle edge cases during replay rather than crash. _Generated with `cmux`_
1 parent c596556 commit 43e5103

File tree

2 files changed

+5
-1
lines changed

2 files changed

+5
-1
lines changed

src/stores/WorkspaceStore.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -964,12 +964,15 @@ export class WorkspaceStore {
964964
const historicalMsgs = this.historicalMessages.get(workspaceId) ?? [];
965965
historicalMsgs.push(data);
966966
this.historicalMessages.set(workspaceId, historicalMsgs);
967-
} else if (isCaughtUp) {
967+
} else if (isCaughtUp && "role" in data) {
968968
// Process live events immediately (after history loaded)
969+
// Check for role field to ensure this is a CmuxMessage
969970
aggregator.handleMessage(data);
970971
this.states.bump(workspaceId);
971972
this.checkAndBumpRecencyIfChanged();
972973
}
974+
// Note: Messages not matching above conditions are silently ignored
975+
// This is expected for malformed messages or events handled elsewhere
973976
// Note: Init events and stream events are handled by isStreamEvent() buffering above
974977
}
975978
}

src/utils/messages/StreamingMessageAggregator.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,7 @@ export class StreamingMessageAggregator {
512512

513513
if (isInitOutput(data)) {
514514
if (!this.initState) return; // Defensive: shouldn't happen but handle gracefully
515+
if (!data.line) return; // Defensive: skip events with missing line data
515516
const line = data.isError ? `ERROR: ${data.line}` : data.line;
516517
this.initState.lines.push(line.trimEnd());
517518
this.invalidateCache();

0 commit comments

Comments
 (0)