ruvnet/ruflo · error

cannot locate the ruflo CLI entrypoint for supervised…

Error message

cannot locate the ruflo CLI entrypoint for supervised service mode

What it means

startBackground() re-execs the CLI as `node <cliEntry> proxy supervise`, taking the entrypoint from process.argv[1]. When argv[1] is empty — Node invoked without a script path — the CLI cannot locate itself for supervised service mode and aborts. This indicates ruflo is being driven through a non-standard entrypoint rather than its bin.

Solutions

  1. Invoke the CLI the normal way: run `ruflo proxy start --service` from a shell
  2. If calling programmatically, set process.argv[1] to the resolved ruflo bin path before calling startBackground()
  3. Prefer spawning `ruflo proxy start --service` as a subprocess from host code rather than importing internals

Example fix

// before (argv[1] missing, e.g. node -e / library context)
await startBackground(); // throws 'cannot locate the ruflo CLI entrypoint'
// after
process.argv[1] = createRequire(import.meta.url).resolve('@claude-flow/cli/bin/ruflo');
await startBackground();
Defensive patterns

Strategy: validation

Validate before calling

if (!process.argv[1]) {
  throw new Error('startBackground needs a CLI entrypoint — run `ruflo proxy start --service` instead');
}
await startBackground();

Type guard

const isMissingEntrypoint = (e: unknown): e is Error =>
  e instanceof Error && /cannot locate the ruflo CLI entrypoint/.test(e.message);

Try / catch

try {
  await startBackground();
} catch (e) {
  if (isMissingEntrypoint(e)) {
    // fall back to spawning the CLI as a subprocess instead of embedding
    spawnSync('ruflo', ['proxy', 'start', '--service'], { stdio: 'inherit' });
  } else throw e;
}

Prevention

When it happens

Trigger: Calling startBackground() programmatically from code embedding the CLI as a library where process.argv[1] is undefined; launch contexts like `node -e`, REPLs, or wrappers that strip argv entries.

Common situations: Custom automation importing lifecycle functions directly instead of shelling out to `ruflo`; test harnesses that stub or truncate process.argv; patched runtimes/bundlers altering argv.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/0641146b560be99c. Report an issue: GitHub.

Appendix: source

Thrown at v3/@claude-flow/cli/src/proxy/lifecycle.ts:222

 * `ruflo` invocation, redirecting stdout/stderr to a real log file (not
 * buffered in-process). Returns once the child's PID is confirmed written,
 * without waiting for the process to exit.
 */
export async function startBackground(): Promise<{ pid: number }> {
  requireBinary();
  const status = getProxyStatus();
  if (status.running && status.pid) throw new ProxyAlreadyRunningError(status.pid);

  const lockFd = acquireStartLock();
  try {
    // Re-check under the lock — the dedup above raced a concurrent starter.
    const rechecked = getProxyStatus();
    if (rechecked.running && rechecked.pid) throw new ProxyAlreadyRunningError(rechecked.pid);
    if (rechecked.stalePidFile) clearStalePidFile();

    const logFd = fs.openSync(proxyLogFilePath(), 'a');
    const cliEntry = process.argv[1];
    if (!cliEntry) throw new Error('cannot locate the ruflo CLI entrypoint for supervised service mode');
    const child = spawn(process.execPath, [cliEntry, 'proxy', 'supervise'], {
      stdio: ['ignore', logFd, logFd],
      detached: true,
      windowsHide: true,
    });
    fs.closeSync(logFd); // the child holds its own duplicated fd; safe to close ours

    if (!child.pid) throw new Error('ruflo proxy supervisor failed to spawn — no PID returned');
    writePidFile(child.pid);
    child.unref();
    return { pid: child.pid };
  } finally {
    releaseStartLock(lockFd);
  }
}

export interface StopResult {
  wasRunning: boolean;

View on GitHub (pinned to fa13ee4ad6)