Skip to content

fix(tui): guard server-synced store fields against null responses - #45322

Open
ofrades wants to merge 1 commit into
anomalyco:devfrom
ofrades:fix/opentui-null-guards
Open

fix(tui): guard server-synced store fields against null responses#45322
ofrades wants to merge 1 commit into
anomalyco:devfrom
ofrades:fix/opentui-null-guards

Conversation

@ofrades

@ofrades ofrades commented Aug 26, 2026

Copy link
Copy Markdown

Issue for this PR

Fixes a recurring TUI crash family:

TypeError: Object.entries requires that input parameter not be null or undefined
    at entries (unknown)
    at w (chunk-...js)

Previously reported as #21014, #20388, #5151 (v1 fixed the MCP slice via #22105 / #22206; this extends the same treatment to the remaining unguarded fields and consumers).

Type of change

  • Bug fix

What does this PR do?

During TUI bootstrap, several endpoints are read with non-null assertions (x.data!):

const providersResponse = providersPromise.then((x) => x.data!)
const providerListResponse = providerListPromise.then((x) => x.data!)
const configResponse = configPromise.then((x) => x.data!)

If any response arrives with null/undefined data (server busy, transient failure, version-mismatched background service restarting mid-bootstrap), that null is written straight into the Solid store. Every component then calling Object.entries/Object.keys/Object.values on it throws inside a reactive computation and kills the whole session with the "OpenCode crashed" screen.

Root fix (context/sync.tsx): replace all bootstrap x.data! assertions with fallback shapes (?? { providers: [], default: {} }, ?? [], ?? {}, ...) so object/array-typed store fields can never receive null.

Defense-in-depth at consumption sites, so even a transiently undefined store value during recomputation cannot crash:

File Change
plugin/adapters.tsx Object.entries(sync.data.mcp)?? {}
component/dialog-status.tsx 3 MCP sites → ?? {}
routes/session/footer.tsx mcp/lsp sites → ?? {} / ?? []
context/local.tsx sync.data.mcp[name]sync.data.mcp?.[name]
theme/index.ts Object.entries(theme.theme)?? {}

How did you verify your code works?

  • bun run typecheck in packages/tui passes (tsgo, no errors)
  • oxlint packages/tui/src reports 0 errors
  • bun test test/cli/cmd/tui/sync.test.tsx passes
  • Repo pre-push hooks (turbo, 30 tasks) passed on push

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

A null/undefined data field from any bootstrap endpoint (providers,
agents, config, console state, MCP status) crashed the TUI with
"Object.entries requires that input parameter not be null or undefined"
inside a Solid.js reactive computation. Non-null assertions in the sync
bootstrap propagated nulls straight into the store.

- replace bootstrap `x.data!` assertions with fallback shapes so the
  store never receives null for object/array-typed fields
- guard every Object.entries/keys/values consumer of sync.data.mcp, lsp
  and theme.theme with ?? fallbacks (defense-in-depth, matching the
  pattern of PRs anomalyco#22105/anomalyco#22206)

Regression family: anomalyco#21014, anomalyco#20388, anomalyco#5151
@github-actions

Copy link
Copy Markdown
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Found a related PR:

This PR appears to address the same crash family (Object.entries on null values). It seems like #44356 may be a prior partial fix or attempt at the same issue. You should verify whether #44356 has already been merged or if #45322 supersedes it with a more comprehensive solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant