{"record":{"id":"870d49dc95417aef","repo":"ruvnet/ruflo","slug":"meta-proxy-did-not-return-a-process-id","errorCode":null,"errorMessage":"Meta-Proxy did not return a process id.","messagePattern":"Meta-Proxy did not return a process id\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/proxy/activation.ts","lineNumber":129,"sourceCode":"  if (!owner) return null;\n  if (!isSupportedOwner(owner.executable, process.platform)) {\n    throw new Error(`Meta-Proxy port owner pid ${owner.pid} is not a recognized Ruflo/MetaHarness binary; refusing to signal it.`);\n  }\n  process.kill(owner.pid, 'SIGTERM');\n  for (let attempt = 0; attempt < 40; attempt++) {\n    await wait(50);\n    const current = await probeEffectiveProxy();\n    if (!current || current.pid !== owner.pid) return owner;\n  }\n  throw new Error(`Stale Meta-Proxy pid ${owner.pid} did not stop.`);\n}\n\nfunction launch(binary: string): number {\n  fs.mkdirSync(path.dirname(proxyLogFilePath()), { recursive: true, mode: 0o700 });\n  const log = fs.openSync(proxyLogFilePath(), 'a', 0o600);\n  try {\n    const child = spawn(binary, [], { detached: true, stdio: ['ignore', log, log], windowsHide: true });\n    if (!child.pid) throw new Error('Meta-Proxy did not return a process id.');\n    child.unref();\n    fs.writeFileSync(proxyPidFilePath(), `${child.pid}\\n`, { mode: 0o600 });\n    return child.pid;\n  } finally { fs.closeSync(log); }\n}\n\nasync function launchAndVerify(binary: string, version: string, wait: Wait): Promise<EffectiveProxy> {\n  const pid = launch(binary);\n  for (let attempt = 0; attempt < 100; attempt++) {\n    await wait(50);\n    const current = await probeEffectiveProxy();\n    if (current?.pid === pid && current.version === version && path.resolve(current.executable) === path.resolve(binary)) return current;\n    if (current && current.pid !== pid) {\n      try { process.kill(pid, 'SIGTERM'); } catch { /* already exited */ }\n      throw new Error(`Competing Meta-Proxy pid ${current.pid} won the port with version ${current.version}.`);\n    }\n  }\n  try { process.kill(pid, 'SIGTERM'); } catch { /* already exited */ }","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/ruvnet/ruflo/blob/29f048fc3b556f857cf2b126d2a84c19d2daa0d0/v3/@claude-flow/cli/src/proxy/activation.ts#L111-L147","documentation":"launch() spawns the meta-proxy binary detached and expects Node to assign a pid. In the rare case child.pid is falsy (spawn failed to create the process), the library throws rather than writing a bogus pid file or returning 0. This is essentially an OS/spawn-level failure surfaced by the library.","triggerScenarios":"Calling launchAndVerify()/effective()/installAndActivateProxy() when spawn() cannot actually start the process — e.g. resource exhaustion (pid exhaustion, fork failure), an extremely restricted sandbox/seccomp profile, or a corrupted binary that spawn refuses synchronously without a normal pid.","commonSituations":"Containers with low process limits (ulimit -u), pid_max exhausted on a busy host, hardened CI runners blocking detached spawns, a truncated/architecture-mismatched meta-proxy binary.","solutions":["Check system process limits (ulimit -u, /proc/sys/kernel/pid_max) and free capacity; retry","Verify the meta-proxy binary is intact and executable for your architecture (file ~/.metaharness/bin/meta-proxy; reinstall via the CLI)","Retry the install/activation once — spawn failures can be transient under load","If in a sandbox/CI, confirm the runner permits detached child processes (setsid) and adjust the sandbox profile"],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"// Preflight: binary must exist, be executable, and system must allow new processes\nconst bin = proxyBinaryPath();\nfs.accessSync(bin, fs.constants.X_OK);\nif (process.version && !bin) throw new Error('meta-proxy binary missing');","typeGuard":"function hasPid(child: { pid?: number | undefined }): child is { pid: number } {\n  return typeof child.pid === 'number' && child.pid > 0;\n}","tryCatchPattern":"try {\n  const res = await installAndActivateProxy(version);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('did not return a process id')) {\n    console.error('Spawn failed at OS level: check process limits (ulimit -u, pid_max) and binary integrity, then retry');\n  } else throw e;\n}","preventionTips":["Keep headroom in process limits on CI runners and containers (raise ulimit -u / pid_max)","Reinstall the binary if it was truncated or built for the wrong architecture","Avoid hardened sandbox profiles that block detached child spawns","Retry once on transient fork failures under load"],"tags":["spawn","process","resources","proxy"],"backgroundTag":"spawn-failed-no-pid","analyzedSha":"29f048fc3b556f857cf2b126d2a84c19d2daa0d0","analyzedAt":"2026-09-01T11:37:30.251Z","contentChangedAt":"2026-09-01T11:37:30.251Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}