{"record":{"id":"fc2fd2ad138a9cbd","repo":"different-ai/openwork","slug":"failed-to-locate-opencode","errorCode":null,"errorMessage":"Failed to locate opencode.","messagePattern":"Failed to locate opencode\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/desktop/electron/runtime.mjs","lineNumber":2274,"sourceCode":"      status: result.status,\n      stdout: result.stdout,\n      stderr: result.stderr,\n    };\n  }\n\n  async function opencodeMcpAuth(projectDir, serverName) {\n    const safeProjectDir = String(projectDir ?? \"\").trim();\n    const safeServerName = String(serverName ?? \"\").trim();\n    if (!safeProjectDir) {\n      throw new Error(\"project_dir is required\");\n    }\n    if (!safeServerName) {\n      throw new Error(\"server_name is required\");\n    }\n\n    const program = resolveBinary(\"opencode\");\n    if (!program) {\n      throw new Error(\"Failed to locate opencode.\");\n    }\n\n    const result = await runShellCommand(program, [\"mcp\", \"auth\", safeServerName], {\n      cwd: safeProjectDir,\n      env: await buildChildEnv(),\n      timeoutMs: 120_000,\n    });\n    return {\n      ok: result.status === 0,\n      status: result.status,\n      stdout: result.stdout,\n      stderr: result.stderr,\n    };\n  }\n\n  async function sandboxCleanupOpenworkContainers() {\n    const candidates = await listOpenworkManagedContainers().catch((error) => {\n      throw error;","sourceCodeStart":2256,"sourceCodeEnd":2292,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/desktop/electron/runtime.mjs#L2256-L2292","documentation":"Thrown by `opencodeMcpAuth` when `resolveBinary(\"opencode\")` returns no path — the runtime cannot find an executable `opencode` binary to run for MCP authentication. This check happens after argument validation but before the process spawn, so it guarantees the CLI exists before shelling out.","triggerScenarios":"`opencode` is not installed, is not on PATH, or the packaged/bundled binary is missing at the location `resolveBinary` searches (dev vs. packaged app layout differences).","commonSituations":"Running the Electron app on a machine where only the npm package (not the standalone opencode binary) is installed; PATH differences between shell and GUI-launched app on macOS; a broken build/package step that omitted the bundled binary; wrong architecture binary.","solutions":["Install the opencode binary and ensure it is on PATH (verify with `which opencode`)","If launching from the desktop app, confirm PATH includes the install location or set it via buildChildEnv","Rebuild/repackage so the bundled opencode binary ships with the app","Check resolveBinary search paths match your install layout"],"exampleFix":"// before\n// resolveBinary('opencode') returns undefined; error thrown\n// after\n// ensure the binary exists before invoking the flow\nimport { execFileSync } from 'node:child_process';\nconst which = execFileSync('which', ['opencode'], { encoding: 'utf8' }).trim();\nif (!which) throw new Error('Install opencode first');","handlingStrategy":"fallback","validationCode":"import { execFileSync } from 'node:child_process';\nfunction opencodeOnPath() {\n  try { execFileSync('which', ['opencode']); return true; }\n  catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await opencodeMcpAuth(projectDir, serverName);\n} catch (e) {\n  if (e.message === 'Failed to locate opencode.') {\n    showError('Install the opencode CLI, then retry');\n  } else throw e;\n}","preventionTips":["Verify `which opencode` works in the GUI-launched environment, not just the terminal","Ship/bundle the opencode binary with the desktop app and test packaged builds","Document PATH setup for non-standard installs","Smoke-test binary resolution on app startup"],"tags":["missing-binary","electron","path","mcp"],"backgroundTag":"command-not-found","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}