← Back to PRs

#23287: fix(node-host): improve ENOENT error when exec workspace dir is missing

by SidQin-cyber open 2026-02-22 05:22 View on GitHub →
size: XS
## Summary - **Problem:** When `exec` runs on a node and the agent workspace directory does not exist, Node.js throws `spawn /bin/sh ENOENT`, misleadingly pointing at the shell binary rather than the real cause (missing `cwd`). - **Why it matters:** Users spend hours debugging a non-existent shell problem when the actual fix is simply creating the workspace directory. - **What changed:** In `src/node-host/invoke.ts`, the `child.on("error")` handler now checks whether a `cwd`-related ENOENT is the real cause and surfaces a clear diagnostic: `working directory does not exist: "<path>" — please create it or check your agent workspace config`. - **What did NOT change:** The spawn call itself is unchanged. If the ENOENT is genuinely about the shell binary (not `cwd`), the original error message is preserved. ## Change Type (select all) - [x] Bug fix - [ ] Feature - [ ] Refactor - [ ] Docs - [ ] Security hardening - [ ] Chore/infra ## Scope (select all touched areas) - [ ] Gateway / orchestration - [x] Skills / tool execution - [ ] Auth / tokens - [ ] Memory / storage - [ ] Integrations - [ ] API / contracts - [ ] UI / DX - [ ] CI/CD / infra ## Linked Issue/PR - Closes #22793 ## User-visible / Behavior Changes - When exec fails because the workspace directory is missing, the error now reads: \`working directory does not exist: "/path/to/workspace" — please create it or check your agent workspace config\` instead of the misleading \`spawn /bin/sh ENOENT\`. ## Security Impact (required) - New permissions/capabilities? \`No\` - Secrets/tokens handling changed? \`No\` - New/changed network calls? \`No\` - Command/tool execution surface changed? \`No\` - Data access scope changed? \`No\` ## Repro + Verification ### Environment - OS: macOS 15.3 (arm64), also applicable to Linux - Runtime: Node v22+ - Integration/channel: Node exec (remote nodes) ### Steps 1. Register a new node/agent pair where the workspace dir does not exist 2. Trigger any exec command (e.g., \`whoami\`) 3. Observe the error message ### Expected - Clear error: \`working directory does not exist: "<path>"\` ### Actual - Before fix: \`spawn /bin/sh ENOENT\` (misleading — implies shell is missing) - After fix: \`working directory does not exist: "<path>" — please create it or check your agent workspace config\` ## Evidence Node.js \`child_process.spawn()\` throws ENOENT when the specified \`cwd\` does not exist, but the error message points at the binary (\`/bin/sh\`) rather than the directory. The fix intercepts ENOENT errors, checks if the \`cwd\` actually exists via \`fs.statSync()\`, and provides a targeted diagnostic if it doesn't. ```typescript child.on("error", (err) => { const nodeErr = err as NodeJS.ErrnoException; if (nodeErr.code === "ENOENT" && cwd) { try { fs.statSync(cwd); } catch { finalize(undefined, \`working directory does not exist: "\${cwd}" — please create it or check your agent workspace config\`); return; } } finalize(undefined, err.message); }); ``` ## Human Verification (required) - Verified scenarios: Reviewed Node.js spawn behavior — ENOENT is thrown for both missing binary and missing cwd; \`fs.statSync\` correctly distinguishes the two cases - Edge cases checked: If cwd exists but binary is missing, the original error message is preserved; if cwd is \`undefined\`, the check is skipped entirely - What I did **not** verify: Live remote node exec with missing workspace dir ## Compatibility / Migration - Backward compatible? \`Yes\` - Config/env changes? \`No\` - Migration needed? \`No\` ## Failure Recovery (if this breaks) - How to disable/revert: Revert the error handler change in \`invoke.ts\` - Files/config to restore: \`src/node-host/invoke.ts\` - Known bad symptoms: None — the check is purely diagnostic ## Risks and Mitigations None — the fix only affects error message text; no behavior or control flow changes. <!-- greptile_comment --> <h3>Greptile Summary</h3> Improved error diagnostics when exec fails due to missing workspace directory by detecting ENOENT errors and checking if the `cwd` exists via `fs.statSync`. Key changes: - Added error handler logic in `runCommand` to intercept ENOENT and provide clearer messaging when the working directory doesn't exist - Error message now points to the actual missing directory instead of misleadingly referencing the shell binary Issues found: - The empty catch block around `fs.statSync` will incorrectly diagnose permission errors (EACCES) and other stat failures as "directory does not exist" - Should use the existing `hasErrnoCode` utility from `src/infra/errors.ts` for consistent errno checking across the codebase <h3>Confidence Score: 3/5</h3> - Safe to merge with fixes for the stat error handling edge case - The core improvement is valid and addresses a real UX pain point. However, the empty catch block around `fs.statSync` creates a logic error where permission denied and other filesystem errors will be misdiagnosed as "directory does not exist." This should be fixed before merging to ensure accurate error reporting. - src/node-host/invoke.ts requires attention for the stat error handling logic <sub>Last reviewed commit: 135ffa7</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs