nexu-io/open-design · error

vela login exited before device authorization started (code

Error message

vela login exited before device authorization started (code ${result.code ?? 'null'}, signal ${result.signal ?? 'null'})

What it means

Raised by the activation-wait path when the child exited cleanly (no 'error' event, no 'still-running') without ever emitting an activation URL, and stderr/stdout had no detail. Embeds exit code and signal for diagnosis. Distinct from 289 because this fires in the post-spawn activation wait, after the immediate-failure grace already passed.

Source

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

    timer.unref?.();
    if (capture.activation.activationUrl) finish({ kind: 'activated' });
  });
  const result = await Promise.race([observed, terminal]);

  if (result.kind === 'activated') return;
  // `close` may win the Promise.race before the 50ms activation poll even
  // though its final drained stdout chunk already populated the capture.
  // Observed activation always owns this child; never launch a duplicate
  // device-auth attempt merely because the child exited immediately after it.
  if (capture.activation.activationUrl) return;
  // Slow but still alive: leave the direct attempt running and let the request
  // return — do NOT kill it or fall back to the proxy.
  if (result.kind === 'still-running') return;
  if (result.kind === 'error') {
    throw new Error(`vela login failed to start: ${result.error.message}`);
  }
  const detail = (capture.stderr || capture.stdout).trim();
  throw new Error(
    detail ||
      `vela login exited before device authorization started (code ${result.code ?? 'null'}, signal ${result.signal ?? 'null'})`,
  );
}

interface SpawnVelaLoginAttemptDeps extends SpawnVelaLoginDeps {
  attempt: VelaLoginAttemptRef;
  onLatePreActivationFailure?: () => Promise<void>;
}

async function spawnVelaLoginAttempt(
  deps: SpawnVelaLoginAttemptDeps,
): Promise<SpawnedVelaLogin> {
  const attemptState = currentVelaLoginAttempt(deps.attempt);
  if (!attemptState) throw new Error('vela login attempt is no longer active');
  if (hasRunningVelaLoginChild()) throw new Error('vela login already running');
  const def = getAgentDef('amr');
  if (!def) {

View on GitHub (pinned to 5be4028344)

Solutions

  1. Inspect exit code/signal: a non-null signal almost always means external kill (sandbox/OOM/timeout).
  2. Confirm the capture reads both stdout and stderr of the configured vela child.
  3. Re-run with proxy fallback enabled so a flaky direct activation can be retried.

Example fix

// before
throw new Error(`vela login exited before device authorization started (code ${result.code ?? 'null'}, signal ${result.signal ?? 'null'})`);

// after
const detail = (capture.stderr || capture.stdout).trim();
throw new Error(
  detail || `vela login exited before device authorization started (code ${result.code ?? 'null'}, signal ${result.signal ?? 'null'})`,
);
Defensive patterns

Strategy: try-catch

Type guard

function isExitedBeforeDeviceAuth(err: unknown): boolean {
  return err instanceof Error
    && /vela login exited before device authorization started/.test(err.message);
}

Try / catch

try {
  await waitForActivation(capture, observed, terminal);
} catch (err) {
  if (isExitedBeforeDeviceAuth(err)) {
    // capture had no activationUrl and child exited; route to proxy fallback
  }
  throw err;
}

Prevention

When it happens

Trigger: vela login ran past the grace window, then exited before printing the device-auth URL with no useful capture. Common when the child is killed externally mid-activation or exits with a code the parser did not treat as an error event.

Common situations: External kill (signal) during activation; vela printed the URL to a stream the capture is not reading; race where close wins before the 50ms activation poll reads the final chunk (the code already defends activationUrl, so this residual means capture truly had none).

Related errors


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