{"record":{"id":"9751b7fe25c3f6a4","repo":"withastro/astro","slug":"timeout","errorCode":null,"errorMessage":"Timeout","messagePattern":"Timeout","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/create-astro/src/shell.ts","lineNumber":71,"sourceCode":"\ttry {\n\t\tconst [resolvedCommand, resolvedFlags] = resolveCommand(command, flags);\n\t\tchild = spawn(resolvedCommand, resolvedFlags, {\n\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 || `Process exited with code ${exitCode}`);\n\t}\n\treturn { stdout, stderr, exitCode };\n}\n","sourceCodeStart":53,"sourceCodeEnd":78,"githubUrl":"https://github.com/withastro/astro/blob/d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca/packages/create-astro/src/shell.ts#L53-L78","documentation":"Thrown by `create-astro`'s `shell()` helper when a spawned child process has `exitCode === null` after the promise settles. A null exit code means the process was killed by a signal or terminated by the spawn timeout rather than exiting normally — most commonly the `timeout` option elapsed and Node killed the process.","triggerScenarios":"Calling `shell(command, flags, { timeout: N })` where the command runs longer than N milliseconds. The child is killed by SIGTERM at the timeout boundary; `child.exitCode` remains null (signal kill, not voluntary exit).","commonSituations":"Running a slow package manager install (`npm install`, `pnpm install`) with a tight timeout during scaffolding. Network-bound git clones exceeding the timeout. A hung interactive prompt blocking the child.","solutions":["Increase or remove the `timeout` option passed to `shell()`.","Ensure the spawned command is non-interactive (pass `--yes`/`--no-input` flags) so it doesn't block waiting for input.","Diagnose the slowness (network, disk, mirror) and fix the root cause rather than extending the timeout indefinitely."],"exampleFix":"// before\nawait shell('npm', ['install'], { timeout: 10_000 });\n\n// after\nawait shell('npm', ['install', '--no-fund', '--no-audit'], { timeout: 120_000 });","handlingStrategy":"try-catch","validationCode":"// Before calling shell(), estimate expected runtime and set timeout comfortably above it.\nconst EXPECTED_INSTALL_MS = 60_000;\nawait shell('npm', ['install'], { timeout: EXPECTED_INSTALL_MS * 3 });","typeGuard":null,"tryCatchPattern":"try {\n  await shell(cmd, flags, { timeout: 60_000 });\n} catch (e) {\n  if (e.message === 'Timeout') { /* retry with longer timeout or non-interactive flags */ }\n  else throw e;\n}","preventionTips":["Set timeouts generously for network-bound commands (install, clone).","Pass non-interactive flags (--yes, --no-input) so children never block on a prompt.","Log wall-clock time of each shell() call to size timeouts correctly."],"tags":["create-astro","cli","process","timeout"],"backgroundTag":null,"analyzedSha":"d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca","analyzedAt":"2026-08-12T13:37:29.035Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}