Skip to content

desktop: file/folder pickers always fail on Windows — request schema rejects undefined for optional options.title / options.extensions ("Desktop IPC handler failed") #50503

Closed

Description

@sbx45

Description

Summary

In OpenCode Desktop 2.0.12 for Windows, opening the native file picker (Ctrl+U / attach button in chat, and folder picker) always fails with the toast "Solicitud fallida / Desktop IPC handler failed". The request never reaches dialog.showOpenDialog. Pasting images (Ctrl+V) and drag & drop work fine.

Root cause (confirmed by in-place instrumentation): the renderer builds the FilesOpenFilePicker request payload with fields set to undefined (title: t?.title, extensions: t?.extensions in openAttachmentPickerDialog), and the desktop IPC request schema requires every field to be present as string | null / array | null. Schema decoding rejects undefined/missing fields, so the request dies before the handler runs. Iteratively patching the payload to send null for title and extensions fixed the picker completely.

Environment

  • opencode version: 2.0.12 (desktop, channel: latest, packaged: true)
  • OS: Windows_NT 10.0.26200 (win32 x64)
  • Terminal: Unavailable (desktop app)
  • Shell: cmd.exe
  • Install/channel: latest (auto-updater reports up-to-date)
  • Active plugins: none

Reproduction

  1. Launch OpenCode Desktop 2.0.12 on Windows.
  2. Open a chat.
  3. Press Ctrl+U (or the attach button) to add a file/image.

Expected Behavior

The native file dialog opens; chosen files are attached.

Actual Behavior

A toast appears: "Solicitud fallida / Desktop IPC handler failed". No dialog opens. The failure is completely silent in all logs (main.log, renderer.log, server log).

With an in-place patch that surfaces the underlying defect in the error message, the actual cause is revealed:

  1. First: Expected string | null at ["options"]["title"]
  2. After sending title: null, the next failure: Expected array | null at ["options"]["extensions"]
  3. After sending null for both fields, the picker works.

The schema definitions (main bundle):

Rl = Qi(L)                                    // string | null
zl = oa({multiple: Qi(ta), title: Rl, defaultPath: Rl})
Bl = oa({multiple: Qi(ta), title: Rl, defaultPath: Rl, extensions: Qi($i(L))})
Gl = R(`FilesOpenFilePicker`, {payload: {options: Qi(Bl)}, ...})

The renderer caller (openAttachmentPickerDialog) sends:

e.openFilePicker({multiple: t?.multiple ?? !1, title: t?.title, defaultPath: t?.defaultPath, extensions: t?.extensions})

title and extensions end up as undefined (they are not required by the callers, e.g. the chat attachment flow passes only {defaultPath, multiple}), and the Effect RPC schema decode rejects them. Either the schema should accept undefined/optional fields, or the client should normalize undefined to null before sending.

A related secondary defect observed in earlier sessions: during first-launch onboarding, app.getPath('documents') failed with Failed to get 'documents' path on this machine (transient; resolved after OS restart), which also surfaced as the same "Desktop IPC handler failed" toast. Separately, the "Configuration file" button failed until ~/.config/opencode/opencode.json was created manually — it would be nicer if that button created/opened the default config instead of failing.

Additional Context

  • Workarounds that always worked: paste images with Ctrl+V, drag & drop files into the chat window.
  • The .NET common file dialog works fine on the same machine (tested via PowerShell), so the Windows shell is healthy — the bug is in the request/schema layer of the desktop app.
  • The failure is completely silent: no log entries anywhere when it happens. Logging the IPC exit defect (console.error on the Die exit in the renderer) showed nothing because the error surfaced through a different path; surfacing the schema error text in the toast was what finally revealed the cause. A log line for failed desktop IPC requests would make such bugs much easier to diagnose.

Plugins

No response

OpenCode version

2.0.12

Steps to reproduce

No response

Screenshot and/or share link

No response

Operating System

No response

Terminal

No response

Activity

  1. github-actions commented on Sep 22, 2026

    @github-actions
    Contributor

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

    Your root-cause analysis (schema rejecting undefined for title/extensions) is a valuable addition — please consider adding it as a comment on #50153 if maintainers decide to close this as a duplicate.

  2. Vibe-coding-nvm-delete-repo commented on Sep 22, 2026

    @Vibe-coding-nvm-delete-repo

    Independent packaged-build confirmation, plus the fix PR for the root cause described here:

    Fix PR: #50333 normalizes undefined at the renderer's request boundary (omit undefined fields, preserve binary payloads) - same root cause, with regression coverage for the picker, directory/save dialogs, openPath and binary uploads.

    Packaged-build evidence (Desktop 2.0.12, Windows 11 10.0.26200, instrumented shipped IPC port):

    • Replaying the pre-fix payload reproduces the exact defect:
      Exit: Failure / Die: "Expected string | null at [\"options\"][\"title\"]"
    • With the normalization applied, the same UI action (Ctrl+U) opens the native picker (#32770 "Choose a file", owned by the app process).

    Method and raw traces: #50333 (comment)

    Scope note for the fix: in the shipped bundle the request boundary (Ut in /out/renderer/assets/main-C16eq30x.js) is shared by every Files*, Menu* and Window* request, so the same undefined-field rejection also covers FilesOpenPath (application), the save dialog and the directory picker - consistent with the PR's regression cases.

    Workarounds that match your findings: paste with Ctrl+V and drag & drop; the failure is silent in main.log/renderer.log because the Die exit never reaches a logger.

  3. Hona commented on Sep 22, 2026

    @Hona
    Member

    Fixed in #50599 (merged to v2 as 8e62ad7). The renderer sent optional picker fields as undefined, which the main process's JSON schema codec rejected before the handler ran. The fix lands in the next desktop release after 2.0.12.

    Workaround until then: drag and drop or paste from the clipboard.

  4. mmarzook3 commented on Sep 22, 2026

    @mmarzook3

    Confirmed on desktop 2.0.13 (latest, packaged, Windows 10.0.26200.9457): the #50599 fix is not in this build.

    Evidence (independent instrumentation of the shipped IPC bridge)

    • Renderer bundle: out/renderer/assets/main-B7CTUSLz.js
    • app.asar sha256: 755CB55C833BCE83FA5D73B27C846EAD0E0537A2A388809791C8C33F408DC8E6
    • Ctrl+U on the attach button (and the "+" → "Images and files" menu item) still produces:
    Exit: Failure / Die: "Expected string | null at [\"options\"][\"title\"]"
      at Wt (oc://renderer/assets/main-B7CTUSLz.js:2:30259)
    

    Timing

    So latest (2.0.13) predates the fix and still ships the bug. Could the next desktop release be confirmed to include #50599 (omit-undefined fields at the renderer IPC boundary)?

    Workarounds that bypass the affected RPCs and keep working: drag & drop, and paste with Ctrl+V.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions