can1357/oh-my-pi · error
Custom shell path not found: ${customShellPath} Please updat
Error message
Custom shell path not found: ${customShellPath}
Please update shellPath in ${configSource} What it means
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.
Source
Thrown at packages/utils/src/procmgr.ts:191
}
/**
* Get shell configuration based on platform.
* Resolution order:
* 1. User-specified shellPath from the active settings source
* 2. On Windows: Git Bash / bash / sh discovery, then cmd.exe (see
* {@link resolveWindowsShell}) — never fails
* 3. On Unix: $SHELL if bash/zsh, then fallback paths
* 4. Fallback: sh
*/
export function getShellConfig(customShellPath?: string, options: ShellConfigOptions = {}): ShellConfig {
const configSource = options.configSource ?? path.join(getAgentDir(), MAIN_CONFIG_FILENAMES[0]);
// 1. Check user-specified shell path. Validated even on the cached path so a
// broken shellPath surfaces its guidance error instead of being masked by an
// earlier successful resolution in the same process.
if (customShellPath) {
if (!fs.existsSync(customShellPath)) {
throw new Error(`Custom shell path not found: ${customShellPath}\nPlease update shellPath in ${configSource}`);
}
if (cachedShellConfig?.shell !== customShellPath) {
cachedShellConfig = buildConfig(customShellPath);
}
return cachedShellConfig;
}
if (cachedShellConfig) {
return cachedShellConfig;
}
if (process.platform === "win32") {
cachedShellConfig = buildConfig(resolveWindowsShell());
return cachedShellConfig;
}
// Unix: prefer user's shell from $SHELL if it's bash/zsh and executable
const userShell = Bun.env.SHELL;
const isValidShell = userShell && (userShell.includes("bash") || userShell.includes("zsh"));View on GitHub (pinned to 9690622007)
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.
Example fix
// before — ~/.omp/config.json
{ "shellPath": "/usr/bin/fish" } // not installed → Error: Custom shell path not found
// after
{ "shellPath": "/bin/bash" } // installed path, or delete shellPath to use the default Defensive patterns
Strategy: try-catch
Validate before calling
import * as fs from "node:fs";
// before calling getShellConfig
const cfg = readShellConfig();
if (cfg.shellPath && !fs.existsSync(cfg.shellPath)) {
logger.warn("Configured shellPath missing; using system default", { shellPath: cfg.shellPath });
delete cfg.shellPath;
} Type guard
function shellExists(p: string): boolean {
try { return fs.statSync(p).isFile(); } catch { return false; }
} Try / catch
let shell;
try {
shell = await getShellConfig();
} catch (err) {
if (err instanceof Error && err.message.startsWith("Custom shell path not found")) {
logger.warn("Falling back to default shell", { message: err.message });
shell = await getShellConfig({ configSource: emptyConfig }); // config without shellPath
} else throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- I/O error occurred
- {}
- ${name} path does not exist: ${trimmed}
- Unable to resolve AWS credentials. Configure static environm
- imageUrls exposure "${name}" requires the ${name} binary on
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/c7a8ded7efb4e99f.
Report an issue: GitHub.