{"record":{"id":"fddff29200b7482e","repo":"ruvnet/ruflo","slug":"ruflo-proxy-supervisor-failed-to-spawn-no-pid-re","errorCode":null,"errorMessage":"ruflo proxy supervisor failed to spawn — no PID returned","messagePattern":"ruflo proxy supervisor failed to spawn — no PID returned","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/proxy/lifecycle.ts","lineNumber":230,"sourceCode":"\n  const lockFd = acquireStartLock();\n  try {\n    // Re-check under the lock — the dedup above raced a concurrent starter.\n    const rechecked = getProxyStatus();\n    if (rechecked.running && rechecked.pid) throw new ProxyAlreadyRunningError(rechecked.pid);\n    if (rechecked.stalePidFile) clearStalePidFile();\n\n    const logFd = fs.openSync(proxyLogFilePath(), 'a');\n    const cliEntry = process.argv[1];\n    if (!cliEntry) throw new Error('cannot locate the ruflo CLI entrypoint for supervised service mode');\n    const child = spawn(process.execPath, [cliEntry, 'proxy', 'supervise'], {\n      stdio: ['ignore', logFd, logFd],\n      detached: true,\n      windowsHide: true,\n    });\n    fs.closeSync(logFd); // the child holds its own duplicated fd; safe to close ours\n\n    if (!child.pid) throw new Error('ruflo proxy supervisor failed to spawn — no PID returned');\n    writePidFile(child.pid);\n    child.unref();\n    return { pid: child.pid };\n  } finally {\n    releaseStartLock(lockFd);\n  }\n}\n\nexport interface StopResult {\n  wasRunning: boolean;\n  pid: number | null;\n}\n\n/** SIGTERM -> 1000ms -> SIGKILL if still alive, mirroring daemon.ts's killBackgroundDaemon. */\nexport async function stopProxy(): Promise<StopResult> {\n  const status = getProxyStatus();\n  if (!status.running || !status.pid) {\n    if (status.stalePidFile) clearStalePidFile();","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/proxy/lifecycle.ts#L212-L248","documentation":"After spawning the detached supervisor (process.execPath + ['proxy', 'supervise']), Node returned a ChildProcess without a pid. The PID is required to write the pid file, so startBackground() aborts before recording anything. This is a rare spawn-level runtime failure — the supervisor never became observable, not a proxy-level crash.","triggerScenarios":"spawn() returning a ChildProcess whose pid is undefined — typically resource exhaustion (fork limits, RLIMIT_NPROC, cgroup pids.max) or a broken runtime where the fork result is unavailable to Node.","commonSituations":"Containers with tight process limits; heavily loaded CI machines; sandboxed environments restricting process creation.","solutions":["Retry the start once — transient resource pressure is the most common cause","Check process limits on the host (`ulimit -u`, container pids.max) and raise them or reduce load","Inspect the service log file for an immediately-exiting supervisor; free resources and run `ruflo proxy start --service` again"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"import { readFileSync } from 'node:fs';\n// Host-level pre-check for hardened Linux environments\ntry {\n  const max = readFileSync('/sys/fs/cgroup/pids.max', 'utf8').trim();\n  if (max !== 'max' && Number(max) < 100) throw new Error('cgroup pids.max too low for the supervisor');\n} catch (e) { if (/pids\\.max/.test(String(e))) throw e; } // absent file/cgroup: skip","typeGuard":"const isSpawnNoPid = (e: unknown): e is Error =>\n  e instanceof Error && /failed to spawn — no PID returned/.test(e.message);","tryCatchPattern":"for (let attempt = 1; attempt <= 2; attempt++) {\n  try {\n    return await startBackground();\n  } catch (e) {\n    if (attempt === 2 || !isSpawnNoPid(e)) throw e;\n    await new Promise(r => setTimeout(r, 500)); // transient resource pressure\n  }\n}","preventionTips":["Raise pid limits (RLIMIT_NPROC / cgroup pids.max) in containers before enabling service mode","Avoid starting the service at peak machine load","After a no-PID failure, check the service log file for an immediately-exiting child"],"tags":["proxy","spawn","resource-limits","service-mode"],"backgroundTag":"process-spawn-failure","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}