{"record":{"id":"697a954db4f48711","repo":"vercel/turborepo","slug":"failed-to-execute-local-turbo-process","errorCode":null,"errorMessage":"Failed to execute local `turbo` process.","messagePattern":"Failed to execute local `turbo` process\\.","errorType":"exception","errorClass":"LocalTurboProcess","httpStatus":null,"severity":"error","filePath":"crates/turborepo-shim/src/run.rs","lineNumber":524,"sourceCode":"    raw_args.append(&mut shim_args.forwarded_args);\n\n    raw_args\n}\n\nfn spawn_child_turbo<R, C, S, V>(\n    runtime: &ShimRuntime<R, C, S, V>,\n    command: process::Command,\n    err: fn(std::io::Error) -> Error,\n) -> ShimResult<R::Error>\nwhere\n    R: TurboRunner,\n    C: ConfigProvider,\n    S: ChildSpawner,\n    V: VersionProvider,\n{\n    let child: Arc<SharedChild> = match runtime.child_spawner.spawn(command) {\n        Ok(child) => child,\n        Err(e) => return ShimResult::ShimError(err(e)),\n    };\n\n    // The child turbo process shares our process group and will receive\n    // SIGINT directly from the kernel when the user presses Ctrl+C.\n    // Ignore SIGINT in the shim *after* spawning so the child inherits\n    // the default disposition (and can register its own handler), while\n    // the shim stays alive to collect the child's exit status.\n    #[cfg(unix)]\n    unsafe {\n        libc::signal(libc::SIGINT, libc::SIG_IGN);\n    }\n\n    let exit_status = match child.wait() {\n        Ok(status) => status,\n        Err(e) => return ShimResult::ShimError(err(e)),\n    };\n    let exit_code = exit_status.code().unwrap_or_else(|| {\n        debug!(\"child turbo failed to report exit code\");","sourceCodeStart":506,"sourceCodeEnd":542,"githubUrl":"https://github.com/vercel/turborepo/blob/f9245100cf0d31d96628804ead485f6bf226e55a/crates/turborepo-shim/src/run.rs#L506-L542","documentation":"The global turbo shim resolved the repo-local turbo binary and tried to spawn it via runtime.child_spawner.spawn(command) (run.rs:524 region); the OS-level spawn failed and is wrapped as Error::LocalTurboProcess with the io::Error preserved as #[source] (run.rs:102-103). The message is intentionally generic — the real cause (ENOENT, EACCES, EMFILE, missing cwd…) is in the chained source error.","triggerScenarios":"Spawning node_modules/.bin/turbo (or the resolved local turbo path) fails: the binary vanished between detection and spawn (ENOENT), is not executable / has a broken shebang (EACCES/ENOEXEC), or the process hit fd/memory limits (EMFILE/ENOMEM).","commonSituations":"Interrupted or partially-applied package-manager install leaving a broken .bin entry Repo copied from Windows/another machine losing the exec bit (WSL DrvFs, chmod issues) Corrupt npx/pnpm-managed shims after a Node version switch","solutions":["Reinstall dependencies (`pnpm install` / `npm install`) to regenerate node_modules/.bin/turbo","Inspect the source error: run `ls -l node_modules/.bin/turbo*` and try executing it directly to see the errno","If EACCES on Linux/WSL: `chmod +x` the binary, or mount the repo with metadata enabled","Install turbo as a direct devDependency so the local binary always exists"],"exampleFix":"# before\nls node_modules/.bin/turbo        # missing or not executable\n# after\npnpm install\nchmod +x node_modules/.bin/turbo  # if needed (WSL/DrvFs)\nnode_modules/.bin/turbo --version","handlingStrategy":"try-catch","validationCode":"// pre-flight the local binary before handing off to the shim\nlet bin = repo.join(\"node_modules/.bin/turbo\");\n#[cfg(unix)]\n{ use std::os::unix::fs::PermissionsExt; assert!(fs::metadata(&bin)?.permissions().mode() & 0o111 != 0); }","typeGuard":"fn spawnable(p: &Path) -> bool { p.is_file() && fs::metadata(p).map(|m| m.permissions().readonly() == false).unwrap_or(false) }","tryCatchPattern":"// the io::Error source carries the errno — branch on it\nmatch run() {\n    Err(Error::LocalTurboProcess(source)) => match source.kind() {\n        std::io::ErrorKind::NotFound => reinstall_deps(),\n        std::io::ErrorKind::PermissionDenied => fix_exec_bit(),\n        _ => return Err(source.into()),\n    },\n    r => r?,\n}","preventionTips":["Pin turbo as a repo devDependency so the local binary always exists","After partial installs or file copies, re-run the package manager before turbo","Keep the exec bit when moving repos across filesystems (WSL DrvFs)"],"tags":["shim","spawn","process","local-turbo","executable"],"backgroundTag":"spawn-executable-failed","analyzedSha":"f9245100cf0d31d96628804ead485f6bf226e55a","analyzedAt":"2026-08-17T10:46:15.696Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}