nexu-io/open-design · error

failed to spawn vela login

Error message

failed to spawn vela login

What it means

Raised in spawnVelaLoginAttempt() after child_process spawn returned a ChildProcess whose pid is not a number. Node sets pid only when the process actually started; a missing pid means spawn synchronously failed to launch (and an 'error' event will follow). Recorded as spawn_result failed/internal_error.

Source

Thrown at apps/daemon/src/integrations/vela.ts:1231

      env,
      detached: false,
      windowsVerbatimArguments: invocation.windowsVerbatimArguments,
    });
  } catch (error) {
    recordVelaAuthStage(
      deps.attempt,
      { stage: 'spawn_result', result: 'failed', errorKind: 'internal_error' },
      'daemon',
    );
    throw error;
  }
  if (typeof child.pid !== 'number') {
    recordVelaAuthStage(
      deps.attempt,
      { stage: 'spawn_result', result: 'failed', errorKind: 'internal_error' },
      'daemon',
    );
    throw new Error('failed to spawn vela login');
  }
  activeLoginProcs.set(child.pid, child);
  pendingVelaLoginTerminals += 1;
  attemptState.currentPid = child.pid;
  recordVelaAuthStage(
    deps.attempt,
    { stage: 'spawn_result', result: 'success' },
    'daemon',
  );
  let spawnReturned = false;
  let terminalHandled = false;
  let activationCapture: VelaLoginActivationCapture | null = null;
  let settleTerminal: (value: VelaLoginChildTerminal) => void = () => undefined;
  const terminal = new Promise<VelaLoginChildTerminal>((resolve) => {
    settleTerminal = resolve;
  });
  const handleTerminal = (
    terminalKind: 'exit' | 'error',

View on GitHub (pinned to 5be4028344)

Solutions

  1. Check ulimits (ulimit -u, ulimit -n) and raise them if the daemon is hitting ceilings.
  2. Reduce concurrent agent spawns; the supervisor already single-flights login, but other agents may be saturating the process table.
  3. If sandboxed, allow fork/exec for the vela binary path.

Example fix

// before
const child = spawn(bin, args, spawnOpts);
if (typeof child.pid !== 'number') throw new Error('failed to spawn vela login');

// after
const child = spawn(bin, args, spawnOpts);
if (typeof child.pid !== 'number') {
  await once(child, 'error'); // surface the real errno from the 'error' event
  throw new Error('failed to spawn vela login');
}
Defensive patterns

Strategy: try-catch

Type guard

function isFailedToSpawn(err: unknown): boolean {
  return err instanceof Error && err.message === 'failed to spawn vela login';
}

Try / catch

try {
  return await spawnVelaLoginAttempt(deps);
} catch (err) {
  if (err instanceof Error && err.message === 'failed to spawn vela login') {
    // almost always resource limits — check ulimit -u / ulimit -n
  }
  throw err;
}

Prevention

When it happens

Trigger: spawn() returned without a pid — typically EAGAIN (out of processes/file descriptors), or a platform-specific spawn failure where Node could not fork/exec. Distinct from ENOENT (which surfaces via the 'error' event and is caught earlier).

Common situations: System at resource limits (max processes, fd ceiling); fork blocked by sandbox/seccomp; malformed env/args causing the launcher to fail before pid assignment; very rare race in packaged Electron spawn.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/0c19bbb14527e1a3. Report an issue: GitHub.