vercel/next.js · error
Command failed: ${command} ${args.join(' ')} (exit ${code})
Error message
Command failed: ${command} ${args.join(' ')} (exit ${code}) What it means
Thrown by runCommand (benchmark.ts:280) when a spawned subprocess (the generate-client-graph script, `next build`, or other node invocations via runCommand) exits with a non-zero code. The message includes the command, its args, and the exit code. The subprocess inherits stdio so its own error output appears above this throw, making the exit cause visible.
Source
Thrown at bench/render-pipeline/benchmark.ts:280
const stddev = Math.sqrt(variance)
const p95 = sorted[Math.max(0, Math.ceil(sorted.length * 0.95) - 1)]
return { min, median, mean, stddev, p95, max }
}
async function runCommand(
command: string,
args: string[],
cwd: string,
env: NodeJS.ProcessEnv = process.env
): Promise<void> {
const child = spawn(command, args, {
cwd,
env,
stdio: 'inherit',
})
const [code] = (await once(child, 'exit')) as [number | null]
if (code !== 0) {
throw new Error(
`Command failed: ${command} ${args.join(' ')} (exit ${code})`
)
}
}
async function ensureNextBuilt() {
try {
await access(NEXT_BIN)
} catch {
throw new Error(
`Missing ${NEXT_BIN}. Build Next.js first (pnpm --filter=next build).`
)
}
}
async function waitForServerReady(
url: string,
timeoutMs: number,View on GitHub (pinned to 0ae8c72462)
Solutions
- Scroll up: the subprocess printed the real error (build error, missing module, etc.) to stdout/stderr before this throw — fix that.
- Reproduce manually: run the exact command + args from the message in the same cwd.
- If it's `next build`, ensure NEXT_BIN exists (pnpm --filter=next build) and the basic-app fixture is in sync with current Next.js.
- If it's the generator, run `node bench/basic-app/scripts/generate-client-graph.mjs` by hand to see the failure.
Example fix
# before — opaque failure # Error: Command failed: node [...]/generate-client-graph.mjs (exit 1) # reproduce to find the real cause node bench/basic-app/scripts/generate-client-graph.mjs # then fix the script/app, then re-run the benchmark
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight the things runCommand will invoke:
import { existsSync } from 'node:fs'
if (!existsSync(NEXT_BIN)) throw new Error('NEXT_BIN missing — build first')
if (!existsSync(resolve(options.appDir, 'scripts/generate-client-graph.mjs'))) {/* optional generator */}
// for next build, you can dry-check the fixture compiles via `next build` manually first Type guard
function isCommandFailure(err: unknown): err is Error {
return err instanceof Error && err.message.startsWith('Command failed:')
} Try / catch
try {
await runCommand('node', [NEXT_BIN, 'build'], options.appDir, env)
} catch (err) {
if (isCommandFailure(err)) {
// the subprocess already printed its error to inherited stdio; just annotate
console.error('\nThe command above exited non-zero. See its output above for the cause.')
}
throw err
} Prevention
- Reproduce the failing command manually (copy command + args from the message) to see the real error in context.
- Keep the fixture app (bench/basic-app) in sync with current Next.js so `next build` stays green.
- Ensure NEXT_BIN is built before benchmarking (error [13]).
- Don't suppress inherited stdio for build steps — the failure text is the diagnosis.
When it happens
Trigger: ensureGeneratedClientGraph running scripts/generate-client-graph.mjs that exits non-zero; `next build` failing on the basic-app fixture (build error in the app); any other runCommand call. Because stdio is 'inherit', the real failure text scrolls by before this error.
Common situations: A broken fixture app that fails to build; the client-graph generator script has a bug or hits a missing dependency; a Next.js source change that breaks the basic-app build; running against an unbuilt NEXT_BIN so `next build` itself errors.
Related errors
- Missing ${NEXT_BIN}. Build Next.js first (pnpm --filter=next
- Command failed: ${command} ${args.join(' ')} (exit ${code})
- Invalid numeric value for --${key}: ${value}
- --routes cannot be empty
- Each route must start with '/': ${route}
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/063453f605417cc3.
Report an issue: GitHub.