Skip to content

Bug Report: TypeError: undefined is not an object (evaluating f.data.map) when entering certain sessions #26560

@LouisYu04

Description

@LouisYu04

Bug Report: TypeError: undefined is not an object (evaluating 'f.data.map') when entering certain sessions

Version

1.14.42

Environment

  • OS: macOS (darwin, arm64)
  • Installation: Binary distribution (~/.opencode/bin/opencode)
  • Database: SQLite (~/.local/share/opencode/opencode.db)

Description

When entering certain sessions via opencode -s <session-id>, the TUI crashes immediately with:

TypeError: undefined is not an object (evaluating 'f.data.map')

This makes those sessions completely inaccessible and the TUI unresponsive.

Root Cause Analysis

The crash occurs in the session.sync method inside the TUI sync context. When syncing a session, the code fetches messages via sdk.client.session.messages() and directly calls .map() on the response data without null-checking:

Packed binary (extracted from ~/.opencode/bin/opencode):

u.message[U]=f.data.map((N)=>N.info);      // ← crashes here
for(let N of f.data)
    u.part[N.info.id]=N.parts;

Source code location (from anomalyco/opencode repo, dev branch):

// packages/opencode/src/cli/cmd/tui/context/sync.tsx:529
draft.message[sessionID] = messages.data!.map((x) => x.info)

The non-null assertion messages.data! is unsafe — the API can return undefined when:

  • The session has no messages (empty session)
  • Message data was cleared or corrupted
  • The API returns an unexpected shape for certain session states

Contrast with Safe Patterns in the Same Code

Other sync operations in the same function correctly use nullish coalescing:

u.todo[U]=j.data??[]           // ✅ guarded
u.session_diff[U]=O.data??[]   // ✅ guarded
u.message[U]=f.data.map(...)   // ❌ unguarded

This inconsistency is what makes the messages sync path uniquely vulnerable.

Reproduction Steps

  1. Create or identify a session that has zero messages or whose message data is in an unexpected state
  2. Run opencode -s <session-id>
  3. The TUI initializes and begins bootstrapping
  4. During session.sync, K.client.session.messages() returns a response where data is undefined
  5. f.data.map(...) throws TypeError: undefined is not an object
  6. TUI crashes or becomes unresponsive

Expected Behavior

Entering any session should gracefully handle empty or malformed message data, treating it as an empty array rather than crashing.

Actual Behavior

The TUI crashes with a TypeError and the session becomes completely inaccessible.

Suggested Fix

In packages/opencode/src/cli/cmd/tui/context/sync.tsx, change line 529 from:

draft.message[sessionID] = messages.data!.map((x) => x.info)
for (const message of messages.data!) {
    draft.part[message.info.id] = message.parts
}

To:

const messageData = messages.data ?? []
draft.message[sessionID] = messageData.map((x) => x.info)
for (const message of messageData) {
    draft.part[message.info.id] = message.parts
}

This mirrors the safe patterns already used for todo and diff in the same function.

Additional Context

  • The crash is not user-code related; it is an internal OpenCode CLI bug.
  • The binary at ~/.opencode/bin/opencode is a Mach-O arm64 executable with the vulnerable JS bundled inside, so users cannot patch this locally.
  • Deleting the problematic session via opencode session delete <id> is a temporary workaround.

Logs

From ~/.local/share/opencode/log/2026-05-09T191324.log:

INFO  service=session id=ses_... slug=... version=1.14.42
...

No explicit error log for the TypeError itself (it likely crashes the TUI process before logging), but the pattern is reproducible from the extracted source.

Metadata

Metadata

Assignees

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