{"record":{"id":"ba14133713f27437","repo":"withastro/astro","slug":"process-exited-with-code-exitcode-ba1413","errorCode":null,"errorMessage":"Process exited with code ${exitCode}","messagePattern":"Process exited with code (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/upgrade/src/shell.ts","lineNumber":75,"sourceCode":"\t\t\tcwd: opts.cwd,\n\t\t\tstdio: opts.stdio,\n\t\t\ttimeout: opts.timeout,\n\t\t});\n\t\tconst done = new Promise<void>((resolve, reject) => {\n\t\t\tchild.once('error', reject);\n\t\t\tchild.once('close', () => resolve());\n\t\t});\n\t\t[stdout, stderr] = await Promise.all([text(child.stdout), text(child.stderr), done]);\n\t} catch (e) {\n\t\tconst message = e instanceof Error ? e.message : stderr || 'Unknown error';\n\t\tthrow new Error(message);\n\t}\n\tconst { exitCode } = child;\n\tif (exitCode === null) {\n\t\tthrow new Error('Timeout');\n\t}\n\tif (exitCode !== 0) {\n\t\tthrow new Error(stderr || stdout || `Process exited with code ${exitCode}`);\n\t}\n\treturn { stdout, stderr, exitCode };\n}\n","sourceCodeStart":57,"sourceCodeEnd":79,"githubUrl":"https://github.com/withastro/astro/blob/d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca/packages/upgrade/src/shell.ts#L57-L79","documentation":"Thrown by the `shell()` helper when the spawned child process exits with a non-zero `exitCode` AND both `stderr` and `stdout` are empty. It is the fallback message format string `Process exited with code ${exitCode}` used only when there is no captured output to report instead. When stderr/stdout is present, that output is thrown in its place, so hitting this exact message means the failure was silent.","triggerScenarios":"A spawned command fails (non-zero exit) without writing anything to stdout or stderr — e.g. killed by a signal that Node translates to a non-zero exit but no output, a binary that exits via `_exit` without flushing, stdio streams closed/redirected away via `opts.stdio`, or a `.exe` shim on Windows that fails before producing output.","commonSituations":"A package manager or git command exits non-zero with output swallowed by a custom `stdio` config; a missing executable resolves but immediately fails; CI environments where stdio is piped/hidden.","solutions":["Reproduce manually: run the same command and flags (`${command} ${flags.join(' ')}`) in the same `opts.cwd` to see the real failure output.","Ensure `opts.stdio` is not set to `'ignore'`/`'pipe'` in a way that discards output — let stderr through for diagnostics.","Check the exit code value to map it to the underlying tool's failure (e.g. git, npm/pnpm error codes).","Confirm the executable exists and is on PATH (a missing binary often surfaces via the catch block, but a broken shim can exit silently)."],"exampleFix":"// before\nif (exitCode !== 0) {\n  throw new Error(stderr || stdout || `Process exited with code ${exitCode}`);\n}\n\n// after — always include the command and exit code for debuggability\nif (exitCode !== 0) {\n  throw new Error(\n    stderr || stdout || `${command} ${flags.join(' ')} exited with code ${exitCode}`,\n  );\n}","handlingStrategy":"try-catch","validationCode":"import { which } from 'node:which'; // or shelljs\nasync function commandAvailable(cmd: string): Promise<boolean> {\n  try { await which(cmd); return true; } catch { return false; }\n}","typeGuard":"function isExitCodeError(e: unknown): boolean {\n  return e instanceof Error && /exited with code \\d+/.test(e.message);\n}","tryCatchPattern":"try {\n  await shell(cmd, flags, { stdio: ['ignore','pipe','pipe'] });\n} catch (e) {\n  // Always preserve stdout/stderr; do not set stdio to 'ignore'\n  if (isExitCodeError(e)) {\n    // re-run manually to capture output, or surface exitCode to the user\n  } else throw e;\n}","preventionTips":["Never set `stdio: 'ignore'` on subprocesses whose failure you need to diagnose.","Capture and log child stdout/stderr in your wrapper so silent failures still leave a trace.","Verify the executable exists and is on PATH before spawning.","Reproduce failing commands manually with the same cwd and flags."],"tags":["subprocess","exit-code","upgrade-tool","spawn","silent-failure"],"backgroundTag":null,"analyzedSha":"d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca","analyzedAt":"2026-08-12T13:37:29.035Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}