Skip to content

session_diff read/write race can trigger Unexpected EOF and local server exit #27843

@waynewang6660

Description

@waynewang6660

Summary

On macOS, the local OpenCode server intermittently "shuts down" or gets torn down by the desktop app. After investigation, this looks like a core session_diff storage/read race rather than an MCP compatibility problem or an oh-my-opencode-specific bug.

The strongest signal is a runtime error in the core read path:

  • FileSystem.readJson
  • SessionSummary.diff
  • SessionHttpApi.diff
  • JSON Parse error: Unexpected EOF

At the same time, the desktop side later records:

  • Killed server
  • Received Exit
  • Server state missing

Environment

  • macOS
  • OpenCode desktop app
  • oh-my-openagent plugin enabled
  • user config stored in ~/.config/opencode/opencode.json

What I observed

1) Core read path fails on JSON parse

From local runtime log (~/.local/share/opencode/log/2026-05-16T084710.log):

ERROR ... service=server error=JSON Parse error: Unexpected EOF cause=SyntaxError: JSON Parse error: Unexpected EOF
at FileSystem.readJson
at SessionSummary.diff
at SessionHttpApi.diff

Relevant excerpt:

ERROR 2026-05-16T08:47:22 +4449ms service=server error=JSON Parse error: Unexpected EOF cause=SyntaxError: JSON Parse error: Unexpected EOF
    at FileSystem.readJson (/$bunfs/root/chunk-n2xqxvv1.js:39:2871)
    at FileSystem.readJson (definition) (/$bunfs/root/chunk-pves1snx.js:679:69219)
    at SessionSummary.diff (/$bunfs/root/chunk-7az0q54r.js:9:19672)
    at SessionSummary.diff (definition) (/$bunfs/root/chunk-tt4khxbr.js:907:1334)
    at SessionHttpApi.diff (/$bunfs/root/chunk-7az0q54r.js:2:92073)
    at SessionHttpApi.diff (definition) (/$bunfs/root/chunk-7az0q54r.js:9:19616) failed

2) The suspicious session_diff file is valid after the fact

The suspected file at the time was:

  • ~/.local/share/opencode/storage/session_diff/ses_1d058a809ffefDO34XA130eE4r.json

I validated it later with Python JSON parsing and it is currently valid JSON, about 2.4MB in size.

This strongly suggests a transient read/write race:

  • writer is updating session_diff
  • reader hits it mid-write
  • readJson() sees partial contents and throws Unexpected EOF

This does not look like a permanently corrupted file on disk.

3) Desktop later tears down the local sidecar/server

From desktop log (~/Library/Logs/ai.opencode.desktop/opencode-desktop_2026-05-13_19-14-28.log):

INFO opencode_lib: Killed server
INFO opencode_lib: Received Exit
INFO opencode_lib: Server state missing

So the user-visible symptom is "server closed itself", but the likely sequence is:

  1. core session_diff read path throws on partial JSON
  2. server enters failure path / exits
  3. desktop app observes loss of server state and tears down or reports server gone

Why I don't think MCP is the primary cause

There are repeated MCP errors like:

  • failed to get prompts
  • failed to get resources
  • MCP error -32601

However, in the same logs MCP clients are still successfully created, e.g. create() successfully created client.
So these look like compatibility/capability-probe noise rather than the fatal trigger.

Why I don't think this is oh-my-openagent-specific

The failure stack is in core session summary / HTTP diff logic, not plugin code:

  • FileSystem.readJson
  • SessionSummary.diff
  • SessionHttpApi.diff

The plugin may increase activity and make the race easier to hit, but the actual read/parse failure appears to be in OpenCode core.

Suspected root cause

A non-atomic or insufficiently guarded write/read flow for storage/session_diff/*.json.

Likely scenarios:

  • direct overwrite write without temp-file + rename
  • no tolerant retry on JSON parse immediately after read
  • concurrent read while write still in progress

Expected behavior

  • session_diff writes should be atomic (e.g. write temp file, fsync if needed, then rename)
  • read path should either:
    • tolerate/retry transient EOF for a short time, or
    • validate file completeness before parse
  • a transient diff read failure should not take down the local server lifecycle

Notes

This also seems directionally related to prior OpenCode discussions around atomic storage writes and session diff corruption / EOF errors.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions