openclaw - ✅(Solved) Fix SSE streaming: empty/missing data event causes JSON parse failure (Unexpected end of JSON input) [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#52679Fetched 2026-04-08 01:20:30
View on GitHub
Comments
1
Participants
2
Timeline
8
Reactions
0
Author
Participants
Timeline (top)
referenced ×6commented ×1cross-referenced ×1

When using streaming (SSE), I intermittently see the run fail with Unexpected end of JSON input. In the gateway logs this correlates with an SSE message/event where the JSON data payload is empty/missing, but the client still tries to JSON.parse it.

This looks like normal SSE behavior (some events/keep-alives may omit data), but the parser currently treats every event as JSON.

Root Cause

When using streaming (SSE), I intermittently see the run fail with Unexpected end of JSON input. In the gateway logs this correlates with an SSE message/event where the JSON data payload is empty/missing, but the client still tries to JSON.parse it.

This looks like normal SSE behavior (some events/keep-alives may omit data), but the parser currently treats every event as JSON.

Fix Action

Fixed

PR fix notes

PR #52740: fix(agents): guard SSE stream against empty data events

Description (problem / solution / changelog)

Summary

SSE streams occasionally emit events with empty or missing data payloads. When this happens, JSON.parse throws and the entire agent run aborts. This PR wraps the stream function to silently skip malformed events, allowing the run to continue.

Changes

  • src/agents/pi-embedded-runner/sse-stream-guard.ts (new): wrapStreamFnWithSseGuard wrapper that catches JSON.parse errors during stream iteration and skips the offending event with a debug log.
  • src/agents/pi-embedded-runner/sse-stream-guard.test.ts (new): Tests verifying that empty-data events are skipped, normal events pass through, and non-JSON errors are re-thrown.
  • src/agents/pi-embedded-runner/extra-params.ts: Apply the guard wrapper as the outermost layer in the stream function composition chain.

Behavior

BeforeAfter
Empty SSE dataJSON.parse throws → run abortsEmpty SSE data → caught → event skipped (debug log) → stream continues

Closes #52679

Changed files

RAW_BUFFERClick to expand / collapse

Summary

When using streaming (SSE), I intermittently see the run fail with Unexpected end of JSON input. In the gateway logs this correlates with an SSE message/event where the JSON data payload is empty/missing, but the client still tries to JSON.parse it.

This looks like normal SSE behavior (some events/keep-alives may omit data), but the parser currently treats every event as JSON.

Environment

  • OpenClaw: 2026.3.13 (cli banner shows commit 61d171a)
  • OS: Linux
  • Node: v25.8.1
  • Transport: observed with SSE; switching models transport to auto reduced but did not eliminate the failures

Observed

  • Some runs abort with:
    • Could not parse message into JSON: (empty payload)
    • then Unexpected end of JSON input

Expected

  • SSE events that have no data should be ignored / skipped (or treated as non-JSON), and should not abort the run.

Repro (best-effort)

  1. Run an embedded agent workload repeatedly (I used a cron job / embedded run loop).
  2. Eventually a stream chunk arrives with only an event: line (or otherwise empty data).
  3. The client attempts to parse it as JSON and the whole run fails.

Evidence

I have a soak-test + focused gateway log capture demonstrating this failure mode:

  • docs/test-artifacts/openclaw/2026-03-23-stability-locate-1/summary.json
  • docs/test-artifacts/openclaw/2026-03-23-stability-locate-1/gateway-logs-focus.txt

(Those paths are from my downstream integration repo; I can share a smaller repro log excerpt if needed.)

Proposed fix

In the SSE parsing path, before attempting JSON.parse(...):

  • If data is missing/undefined OR data.trim() is empty, skip the event.
  • Optionally log at debug level (once per session) that an empty-data SSE event was ignored.

This is the exact guard that eliminated the dominant failure mode in my soak test.

extent analysis

Fix Plan

To resolve the issue, we need to modify the SSE parsing path to handle empty data payloads. Here are the concrete steps:

  • Check if data is missing or empty before attempting to parse it as JSON
  • Skip the event if data is empty
  • Optionally log a debug message to indicate that an empty-data SSE event was ignored

Example Code

// Check if data is missing or empty
if (!data || data.trim() === '') {
  // Skip the event
  return;
}

// Optionally log a debug message
if (!this.emptyDataLogged) {
  console.debug('Empty-data SSE event ignored');
  this.emptyDataLogged = true;
}

// Attempt to parse data as JSON
try {
  const jsonData = JSON.parse(data);
  // Process the JSON data
} catch (error) {
  console.error('Error parsing JSON:', error);
}

Verification

To verify that the fix worked, you can:

  • Run the same workload repeatedly to see if the Unexpected end of JSON input error still occurs
  • Check the logs to see if the debug message is printed when an empty-data SSE event is ignored
  • Verify that the run no longer aborts when an empty-data SSE event is received

Extra Tips

  • Make sure to handle any potential errors that may occur during JSON parsing
  • Consider adding additional logging or monitoring to detect any other potential issues with SSE events
  • Review the SSE parsing path to ensure that it is correctly handling all possible event types and payloads.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING