Skip to content

Conversation

@junhoyeo
Copy link

Summary

Fixes crash when local.agent.current() is called before agents are loaded (e.g., after OAuth flow or during initial startup).

Error:

TypeError: undefined is not an object (evaluating 'local.agent.current().name')
    at <anonymous> (src/cli/cmd/tui/component/prompt/index.tsx:840:75)

Root Cause

In packages/opencode/src/cli/cmd/tui/context/local.tsx, the agent store initialization assumes agents are always available:

// Before (crashes when agents() is empty)
const [agentStore, setAgentStore] = createStore<{
  current: string
}>({
  current: agents()[0].name,  // CRASH: agents()[0] is undefined
})

This happens because:

  1. sync.data.agent starts as an empty array
  2. LocalProvider initializes before bootstrap() fetches agents
  3. Accessing agents()[0].name crashes when array is empty

Changes

packages/opencode/src/cli/cmd/tui/context/local.tsx:

  • Make agent store current optional and use ?. on initialization
  • Rewrite current() to safely return undefined when no agents available (matches web app implementation)
  • Update set() and move() methods to handle empty agent list
  • Guard currentModel memo and model functions against undefined agent
  • Add null check in createEffect for agent model sync

packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx:

  • Add early return guard in submit() when no agent selected
  • Update highlight() and spinnerDef() memos with fallback colors
  • Use optional chaining with fallback in JSX display

packages/opencode/src/cli/cmd/tui/component/dialog-agent.tsx:

  • Use optional chaining for current agent name prop

Testing

  • Verified no TypeScript errors in modified files
  • Fix aligns with the safer implementation already present in packages/app/src/context/local.tsx

When sync.data.agent is empty (e.g., during oauth flow or initial load),
local.agent.current() would crash accessing undefined.name.

Changes:
- Make agent store initialization safe with optional chaining
- Rewrite current() to handle empty agents list (return undefined)
- Update set()/move() methods to handle undefined/empty list
- Guard all call sites in model functions and createEffect
- Add null checks in prompt component and dialog-agent

This matches the safer implementation already present in packages/app.
@github-actions
Copy link
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
Contributor

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

Potential Duplicate PRs Found

Based on the search results, there are two highly related PRs that appear to address the same issue:

  1. PR fix(tui): guard local.agent.current() after oauth redirect (fixes #7727) #7747 - fix(tui): guard local.agent.current() after oauth redirect (fixes #7727)

  2. PR fix(tui): handle undefined agent.current() to prevent fatal TypeError #7689 - fix(tui): handle undefined agent.current() to prevent fatal TypeError

Recommendation: Check if PR #7747 or #7689 are already merged or open. If either is already in progress or merged, PR #7748 may be redundant and should be consolidated or closed.

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