ruvnet/ruflo · error

Refusing to probe non-loopback Meta-Proxy bind "${bind}".

Error message

Refusing to probe non-loopback Meta-Proxy bind "${bind}".

What it means

effectiveEndpoint() reads the Meta-Proxy config file's `bind` value (defaulting to 127.0.0.1:11435) before probing the daemon. If the configured bind address is not a loopback address, the library refuses to probe it, because probing (and later signaling) a proxy listening on a non-loopback interface could affect other machines' daemons. This is a deliberate safety guard in the library, not a network failure.

Source

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

} from './paths.js';

export interface EffectiveProxy { version: string; pid: number; executable: string; }
type Wait = (milliseconds: number) => Promise<void>;
const waitNormally: Wait = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));

function processExists(pid: number): boolean {
  try { process.kill(pid, 0); return true; } catch (error) {
    return (error as NodeJS.ErrnoException).code === 'EPERM';
  }
}

function effectiveEndpoint(): string {
  let bind = '127.0.0.1:11435';
  try {
    const match = fs.readFileSync(proxyConfigPath(), 'utf8').match(/^bind\s*=\s*"([^"]+)"\s*$/m);
    if (match?.[1]) bind = match[1];
  } catch { /* documented default */ }
  if (!isLoopbackBind(bind)) throw new Error(`Refusing to probe non-loopback Meta-Proxy bind "${bind}".`);
  return `http://${bind}`;
}

function executableFor(pid: number, platform: NodeJS.Platform): string | null {
  try {
    if (platform === 'linux') {
      const result = spawnSync('readlink', ['-f', `/proc/${pid}/exe`], { encoding: 'utf8', timeout: 2_000 });
      return result.status === 0 ? result.stdout.trim() || null : null;
    }
    if (platform === 'win32') {
      const command = `$p = Get-CimInstance Win32_Process -Filter 'ProcessId = ${pid}'; if ($null -ne $p) { [Console]::Out.Write($p.ExecutablePath) }`;
      const result = spawnSync('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', command], { encoding: 'utf8', timeout: 2_000, windowsHide: true });
      return result.status === 0 ? result.stdout.trim() || null : null;
    }
    const result = spawnSync('ps', ['-p', String(pid), '-o', 'comm='], { encoding: 'utf8', timeout: 2_000 });
    return result.status === 0 ? result.stdout.trim() || null : null;
  } catch { return null; }
}

View on GitHub (pinned to 29f048fc3b)

Solutions

  1. Edit the Meta-Proxy config file (see proxyConfigPath(), typically under ~/.metaharness) and set bind to a loopback address, e.g. bind = "127.0.0.1:11435"
  2. If you intentionally need a non-loopback bind, run/probe the daemon yourself outside this library's activation flow; the CLI will not probe non-loopback endpoints by design
  3. Remove the bind line entirely to fall back to the documented default 127.0.0.1:11435
  4. Verify the parsed value is loopback before activating: node -e "console.log(require('net').isLoopback?.(...) )" or check the address manually

Example fix

// before (proxy config)
bind = "0.0.0.0:11435"
// after
bind = "127.0.0.1:11435"
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'node:fs';
// Read the same bind the library will use and reject non-loopback before calling.
const cfg = fs.readFileSync(proxyConfigPath(), 'utf8');
const bind = cfg.match(/^bind\s*=\s*"([^"]+)"\s*$/m)?.[1] ?? '127.0.0.1:11435';
const host = bind.split(':')[0];
if (!(host === 'localhost' || host === '127.0.0.1' || host === '::1' || host === '[::1]')) {
  throw new Error(`Fix bind in proxy config first: "${bind}" is not loopback`);
}
await installAndActivateProxy(version);

Type guard

function isLoopbackBind(bind: string): boolean {
  const host = bind.replace(/^\[|\]$/g, '').split(':')[0];
  return host === 'localhost' || host === '127.0.0.1' || host === '::1' || host.endsWith('.127.0.0.1') || /^127\./.test(host);
}

Try / catch

null

Prevention

When it happens

Trigger: Calling any function that resolves the effective endpoint (probeEffectiveProxy, installAndActivateProxy via stopEffective/launchAndVerify) while proxyConfigPath()'s config contains a `bind = "..."` line whose value is not loopback (e.g. "0.0.0.0:11435", "192.168.1.10:11435", a hostname, or a non-loopback IP).

Common situations: Users edit the Meta-Proxy config to expose the proxy on a LAN address or all interfaces so other hosts/containers can reach it; Docker/Kubernetes setups binding 0.0.0.0; copy-pasted config from a remote-server guide; a stale config left by a manual daemon setup.

Related errors


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