Skip to content

fix(app): session-header crashes when switching projects #16467

Closed

Description

@mariusdill

Description

When switching between open projects in the OpenCode web UI, the application occasionally crashes with:

TypeError: can't access property "id", s() is undefined

This occurs in the session-header component when the current() memo returns undefined during the transition period between projects. The minified code s() corresponds to the current() accessor.

Steps to reproduce

  1. Open multiple projects in OpenCode web UI
  2. Switch between projects quickly (click different projects in the sidebar)
  3. Occasionally the app will crash with the TypeError

Root cause

In packages/app/src/components/session/session-header.tsx, line 306:

const current = createMemo(() => options().find((o) => o.id === prefs.app) ?? options()[0])

When options() is temporarily empty during project switching (race condition during cleanup/re-render), options()[0] returns undefined, causing subsequent accesses like current().id to throw.

Proposed fix

Add a hardcoded fallback object to ensure current() never returns undefined:

const current = createMemo(() => options().find((o) => o.id === prefs.app) ?? options()[0] ?? { id: "finder", label: "Finder", icon: "finder" })

This ensures the "Open in..." dropdown always has a valid selection.

Environment

  • OpenCode version: 1.2.20
  • OS: Nobara Linux 43
  • Browser: Zen 1.19.1b (Firefox 148.0)

Activity

  1. github-actions commented on Mar 7, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

  2. cyberprophet commented on Mar 7, 2026

    @cyberprophet
    Contributor

    Confirmed Root Cause

    This is the same bug as #16459. The crash is in packages/app/src/components/session/session-header.tsx line 306:

    const current = createMemo(() => options().find((o) => o.id === prefs.app) ?? options()[0])

    During project switching, options() briefly becomes an empty array (race condition between cleanup and re-render), so options()[0] returns undefined. The subsequent current().id access on line 421 throws.

    Proposed Fix

    const current = createMemo(
      () => options().find((o) => o.id === prefs.app) ?? options()[0] ?? { id: "finder", label: "Finder", icon: "finder" } as const
    )

    The hardcoded fallback { id: "finder", ... } ensures current() is always a valid object. This is safer than the PR description's suggestion because it doesn't require changing the downstream call sites — current().id remains safe without optional chaining.

    A fix PR is incoming that addresses this.

  3. added a commit that references this issue on Mar 7, 2026
    99d5e6a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

webRelates to opencode on web / desktop

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions