Skip to content

fix(tui): add null guards for lsp and mcp state data#20444

Open
Echoziness wants to merge 3 commits intoanomalyco:devfrom
Echoziness:fix/lsp-mcp-null-guard
Open

fix(tui): add null guards for lsp and mcp state data#20444
Echoziness wants to merge 3 commits intoanomalyco:devfrom
Echoziness:fix/lsp-mcp-null-guard

Conversation

@Echoziness
Copy link
Copy Markdown

@Echoziness Echoziness commented Apr 1, 2026

Issue for this PR

Closes #20443

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Problem: The TUI crashes when the sidebar renders the LSP/MCP status panel before the corresponding services finish initialization. During this brief window, sync.data.lsp is undefined (not yet an array) and sync.data.mcp is undefined (not yet an object), causing:

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

Root cause: Three files access sync.data.lsp and sync.data.mcp without null checks, unlike other methods in the same codebase (message, permission, question, part) which already use ?? [] fallbacks.

Files changed:

File Change
packages/opencode/src/cli/cmd/tui/plugin/api.tsx Added ?? [] to lsp() and ?? {} to mcp()
packages/opencode/src/cli/cmd/tui/component/dialog-status.tsx Added null guards for MCP/LSP rendering in status dialog
packages/opencode/src/cli/cmd/tui/routes/session/footer.tsx Added null guards for MCP/LSP stats in footer

Why this fix works: The ?? operator returns the right-hand side only when the left-hand side is null or undefined. This matches the existing pattern used throughout api.tsx and ensures the code handles the uninitialized state gracefully without changing behavior once services are ready.

How did you verify your code works?

  1. Code review: Verified all 3 files now consistently use null guards, matching the pattern already established in api.tsx for message(), permission(), question(), and part() methods.
  2. Unit tests: All unit tests pass (unit (linux) and unit (windows) CI checks green).
  3. Type safety: The ?? [] and ?? {} operators preserve type inference — TypeScript correctly infers the return types remain Array<{id, root, status}> and [string, MCPStatus][] respectively.
  4. No behavior change: When services are initialized (the normal case), sync.data.lsp is already an array and sync.data.mcp is already an object, so the ?? fallback is never triggered. The fix only affects the uninitialized edge case.

Screenshots / recordings

N/A — This is a non-visual crash fix. The change prevents a TypeError that occurs before any UI can be rendered.

Checklist

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

@github-actions github-actions bot added needs:compliance This means the issue will auto-close after 2 hours. needs:issue labels Apr 1, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

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.

@Echoziness Echoziness force-pushed the fix/lsp-mcp-null-guard branch from b0cbdab to 3508458 Compare April 1, 2026 10:21
Prevents crash when sidebar renders LSP/MCP panels before services
are initialized. sync.data.lsp and sync.data.mcp can be undefined
during initial load, causing TypeError on .map() and Object.entries().

Fixes crash: 'undefined is not an object (evaluating sync8.data.lsp.map)'
@Echoziness Echoziness force-pushed the fix/lsp-mcp-null-guard branch from 3508458 to 3d53271 Compare April 1, 2026 10:22
@github-actions github-actions bot removed needs:compliance This means the issue will auto-close after 2 hours. needs:issue labels Apr 1, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

Thanks for updating your PR! It now meets our contributing guidelines. 👍

@Echoziness
Copy link
Copy Markdown
Author

Echoziness commented Apr 1, 2026

Note on the initial typecheck failure

The first typecheck run failed with ../app/node_modules/.ts-dist/src/i18n/ru.d.ts(757,24): error TS1002: Unterminated string literal. This is in an auto-generated .d.ts file inside node_modules, not in any source code this PR touches. Re-running the check resolved it, confirming this is an intermittent issue in Bun/tsgo declaration file generation rather than a code problem.

The e2e (linux/windows) failures are a known issue affecting all open PRs and are unrelated to this change.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Crash: sync.data.lsp is undefined when sidebar renders LSP panel

1 participant