ruvnet/ruflo · error

Meta-Proxy did not return a process id.

Error message

Meta-Proxy did not return a process id.

What it means

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.

Source

Thrown at v3/@claude-flow/cli/src/proxy/activation.ts:129

  if (!owner) return null;
  if (!isSupportedOwner(owner.executable, process.platform)) {
    throw new Error(`Meta-Proxy port owner pid ${owner.pid} is not a recognized Ruflo/MetaHarness binary; refusing to signal it.`);
  }
  process.kill(owner.pid, 'SIGTERM');
  for (let attempt = 0; attempt < 40; attempt++) {
    await wait(50);
    const current = await probeEffectiveProxy();
    if (!current || current.pid !== owner.pid) return owner;
  }
  throw new Error(`Stale Meta-Proxy pid ${owner.pid} did not stop.`);
}

function launch(binary: string): number {
  fs.mkdirSync(path.dirname(proxyLogFilePath()), { recursive: true, mode: 0o700 });
  const log = fs.openSync(proxyLogFilePath(), 'a', 0o600);
  try {
    const child = spawn(binary, [], { detached: true, stdio: ['ignore', log, log], windowsHide: true });
    if (!child.pid) throw new Error('Meta-Proxy did not return a process id.');
    child.unref();
    fs.writeFileSync(proxyPidFilePath(), `${child.pid}\n`, { mode: 0o600 });
    return child.pid;
  } finally { fs.closeSync(log); }
}

async function launchAndVerify(binary: string, version: string, wait: Wait): Promise<EffectiveProxy> {
  const pid = launch(binary);
  for (let attempt = 0; attempt < 100; attempt++) {
    await wait(50);
    const current = await probeEffectiveProxy();
    if (current?.pid === pid && current.version === version && path.resolve(current.executable) === path.resolve(binary)) return current;
    if (current && current.pid !== pid) {
      try { process.kill(pid, 'SIGTERM'); } catch { /* already exited */ }
      throw new Error(`Competing Meta-Proxy pid ${current.pid} won the port with version ${current.version}.`);
    }
  }
  try { process.kill(pid, 'SIGTERM'); } catch { /* already exited */ }

View on GitHub (pinned to 29f048fc3b)

Solutions

  1. Check system process limits (ulimit -u, /proc/sys/kernel/pid_max) and free capacity; retry
  2. Verify the meta-proxy binary is intact and executable for your architecture (file ~/.metaharness/bin/meta-proxy; reinstall via the CLI)
  3. Retry the install/activation once — spawn failures can be transient under load
  4. If in a sandbox/CI, confirm the runner permits detached child processes (setsid) and adjust the sandbox profile

Example fix

null
Defensive patterns

Strategy: try-catch

Validate before calling

// Preflight: binary must exist, be executable, and system must allow new processes
const bin = proxyBinaryPath();
fs.accessSync(bin, fs.constants.X_OK);
if (process.version && !bin) throw new Error('meta-proxy binary missing');

Type guard

function hasPid(child: { pid?: number | undefined }): child is { pid: number } {
  return typeof child.pid === 'number' && child.pid > 0;
}

Try / catch

try {
  const res = await installAndActivateProxy(version);
} catch (e) {
  if (e instanceof Error && e.message.includes('did not return a process id')) {
    console.error('Spawn failed at OS level: check process limits (ulimit -u, pid_max) and binary integrity, then retry');
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of ruvnet/ruflo@29f048fc3b (2026-09-01). Data as JSON: /api/errors/870d49dc95417aef. Report an issue: GitHub.