{"record":{"id":"c7a8ded7efb4e99f","repo":"can1357/oh-my-pi","slug":"custom-shell-path-not-found-customshellpath-pl","errorCode":null,"errorMessage":"Custom shell path not found: ${customShellPath}\nPlease update shellPath in ${configSource}","messagePattern":"Custom shell path not found: (.+?)\nPlease update shellPath in (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/utils/src/procmgr.ts","lineNumber":191,"sourceCode":"}\n\n/**\n * Get shell configuration based on platform.\n * Resolution order:\n * 1. User-specified shellPath from the active settings source\n * 2. On Windows: Git Bash / bash / sh discovery, then cmd.exe (see\n *    {@link resolveWindowsShell}) — never fails\n * 3. On Unix: $SHELL if bash/zsh, then fallback paths\n * 4. Fallback: sh\n */\nexport function getShellConfig(customShellPath?: string, options: ShellConfigOptions = {}): ShellConfig {\n\tconst configSource = options.configSource ?? path.join(getAgentDir(), MAIN_CONFIG_FILENAMES[0]);\n\t// 1. Check user-specified shell path. Validated even on the cached path so a\n\t// broken shellPath surfaces its guidance error instead of being masked by an\n\t// earlier successful resolution in the same process.\n\tif (customShellPath) {\n\t\tif (!fs.existsSync(customShellPath)) {\n\t\t\tthrow new Error(`Custom shell path not found: ${customShellPath}\\nPlease update shellPath in ${configSource}`);\n\t\t}\n\t\tif (cachedShellConfig?.shell !== customShellPath) {\n\t\t\tcachedShellConfig = buildConfig(customShellPath);\n\t\t}\n\t\treturn cachedShellConfig;\n\t}\n\tif (cachedShellConfig) {\n\t\treturn cachedShellConfig;\n\t}\n\n\tif (process.platform === \"win32\") {\n\t\tcachedShellConfig = buildConfig(resolveWindowsShell());\n\t\treturn cachedShellConfig;\n\t}\n\n\t// Unix: prefer user's shell from $SHELL if it's bash/zsh and executable\n\tconst userShell = Bun.env.SHELL;\n\tconst isValidShell = userShell && (userShell.includes(\"bash\") || userShell.includes(\"zsh\"));","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/procmgr.ts#L173-L209","documentation":"getShellConfig resolves the shell used to spawn processes. If the user configured a custom shellPath and that path does not exist on disk, it throws this error pointing at both the missing path and the config file where shellPath is set. The check runs even when a cached shell config exists, so a broken shellPath always surfaces actionable guidance instead of silently using a stale cached resolution.","triggerScenarios":"Setting shellPath in the agent config (e.g. ~/.omp/config.json or whatever MAIN_CONFIG_FILENAMES[0] is) to a nonexistent binary — typo in the path, uninstalled shell (e.g. /usr/bin/fish not installed), shell removed after an upgrade, or a Windows path used on WSL/macOS.","commonSituations":"Syncing dotfiles across machines where the shell exists on one but not another, switching from zsh to nushell without installing it, pointing shellPath at a version-manager shims directory (nvm/pyenv) that changed, container images lacking the configured shell.","solutions":["Verify the path exists: ls -l <path> — fix shellPath in the config file named in the error message.","Install the missing shell (apt/brew install fish etc.) or correct the binary name (e.g. /bin/bash vs /usr/bin/bash).","Remove the shellPath key to fall back to the system default shell ($SHELL or COMSPEC).","Point to a portable interpreter (/bin/sh, /bin/bash) in shared/container configs.","If the path exists but still fails, check exec permission (chmod +x) and that it isn't a broken symlink."],"exampleFix":"// before — ~/.omp/config.json\n{ \"shellPath\": \"/usr/bin/fish\" } // not installed → Error: Custom shell path not found\n// after\n{ \"shellPath\": \"/bin/bash\" } // installed path, or delete shellPath to use the default","handlingStrategy":"try-catch","validationCode":"import * as fs from \"node:fs\";\n// before calling getShellConfig\nconst cfg = readShellConfig();\nif (cfg.shellPath && !fs.existsSync(cfg.shellPath)) {\n  logger.warn(\"Configured shellPath missing; using system default\", { shellPath: cfg.shellPath });\n  delete cfg.shellPath;\n}","typeGuard":"function shellExists(p: string): boolean {\n  try { return fs.statSync(p).isFile(); } catch { return false; }\n}","tryCatchPattern":"let shell;\ntry {\n  shell = await getShellConfig();\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith(\"Custom shell path not found\")) {\n    logger.warn(\"Falling back to default shell\", { message: err.message });\n    shell = await getShellConfig({ configSource: emptyConfig }); // config without shellPath\n  } else throw err;\n}","preventionTips":["Validate shellPath at config-load time (fs.existsSync) and warn early.","Use absolute paths and portable shells (/bin/bash, /bin/sh) in shared/dotfile configs.","After switching shells or upgrading OS/images, re-test that the configured path exists.","Never point shellPath at version-manager shims that may disappear; resolve them to real binaries."],"tags":["shell","configuration","file-not-found","environment"],"backgroundTag":"executable-path-not-found","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}