{"record":{"id":"560108e34c4ef502","repo":"Yeachan-Heo/oh-my-codex","slug":"sparkshell-raw-fallback-failed-executable-not-f","errorCode":null,"errorMessage":"[sparkshell] raw fallback failed: executable not found (${invocation.argv[0]})","messagePattern":"\\[sparkshell\\] raw fallback failed: executable not found \\((.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/sparkshell.ts","lineNumber":392,"sourceCode":"}\n\nfunction runSparkShellFallback(args: readonly string[], options: RunSparkShellFallbackOptions = {}): void {\n  const { announce = true, cause = 'native sidecar unavailable', nativePath = 'native-resolution', state = 'unavailable' } = options;\n  const invocation = parseSparkShellFallbackInvocation(args);\n  if (announce) {\n    process.stderr.write(`[sparkshell] native sidecar unavailable; cause=${sanitizeFallbackDiagnostic(cause)}; path=${sanitizeFallbackDiagnostic(nativePath)}; state=${sanitizeFallbackDiagnostic(state)}; remediation=install a compatible native sidecar, reconnect for hydration, or set ${OMX_SPARKSHELL_BIN_ENV}. Falling back to raw command execution without summary support.\\n`);\n  }\n  const result = spawnSync(invocation.argv[0], invocation.argv.slice(1), {\n    cwd: process.cwd(),\n    env: process.env,\n    stdio: 'inherit',\n    encoding: 'utf-8',\n  });\n  if (result.error) {\n    const errno = result.error as NodeJS.ErrnoException;\n    const kind = classifySpawnError(errno);\n    if (kind === 'missing') {\n      throw new Error(`[sparkshell] raw fallback failed: executable not found (${invocation.argv[0]})`);\n    }\n    if (kind === 'blocked') {\n      throw new Error(`[sparkshell] raw fallback failed: executable is blocked (${errno.code || 'blocked'})`);\n    }\n    throw new Error(`[sparkshell] raw fallback failed: ${errno.message}`);\n  }\n  if (result.status !== 0) {\n    process.exitCode = typeof result.status === 'number'\n      ? result.status\n      : resolveSignalExitCode(result.signal);\n  }\n}\n\nexport async function sparkshellCommand(args: string[]): Promise<void> {\n  if (args[0] === '--help' || args[0] === '-h') {\n    console.log(SPARKSHELL_USAGE);\n    return;\n  }","sourceCodeStart":374,"sourceCodeEnd":410,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/cli/sparkshell.ts#L374-L410","documentation":"The sparkshell fallback path tried to spawn the resolved program (invocation.argv[0], e.g. `tmux`) via spawnSync and got ENOENT-classified error: the executable is not on PATH or does not exist. The fallback is only reached after the native sparkshell binary also failed to launch.","triggerScenarios":"No tmux installed (or not in PATH of the sparkshell process) while using --tmux-pane mode after the native binary failed.","commonSituations":"Minimal containers/CI images without tmux; PATH stripped or overridden when invoking node; nvm/asdf shims hiding tmux.","solutions":["Install tmux (`apt-get install tmux` / `brew install tmux`)","Verify PATH includes tmux: `which tmux` in the same shell/environment that runs sparkshell","Set the sparkshell binary env override so the native path is used instead of falling back"],"exampleFix":"# before (tmux missing)\nsparkshell --tmux-pane 0\n# after\napt-get install -y tmux\nsparkshell --tmux-pane 0","handlingStrategy":"validation","validationCode":"import { spawnSync } from 'node:child_process';\nconst probe = spawnSync('tmux', ['-V'], { encoding: 'utf-8' });\nif (probe.error) throw new Error('tmux not available on PATH');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Probe for tmux with `tmux -V` before using pane mode in scripts","Ensure CI images install tmux if pane capture is used"],"tags":["spawn","tmux","path","environment"],"backgroundTag":"executable-not-found","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}