nexu-io/open-design · error
vela login already running
Error message
vela login already running
What it means
Single-flight guard in beginVelaLoginAttempt(): it refuses to start a new login if isVelaLoginInFlight() is true, i.e. there is a running login child process or a pending non-canceled fallback. The vela login flow is designed around one supervised attempt at a time keyed by an authAttemptId/generation pair.
Source
Thrown at apps/daemon/src/integrations/vela.ts:1011
if (!input || typeof input !== 'object' || Array.isArray(input)) return null;
const value = (input as { authAttemptId?: unknown }).authAttemptId;
return isCanonicalAmrAuthAttemptId(value) ? value : null;
}
export function parseVelaAuthRequestId(input: unknown): string | null {
if (!input || typeof input !== 'object' || Array.isArray(input)) return null;
const value = (input as { authRequestId?: unknown }).authRequestId;
return typeof value === 'string'
&& /^pending-amr-auth-[a-z0-9]+-[a-z0-9]+$/.test(value)
? value
: null;
}
function beginVelaLoginAttempt(
authAttemptId?: string | null,
authRequestId?: string | null,
): VelaLoginAttemptRef {
if (isVelaLoginInFlight()) throw new Error('vela login already running');
const attempt: VelaLoginAttemptState = {
authAttemptId: isCanonicalAmrAuthAttemptId(authAttemptId)
? authAttemptId
: randomUUID(),
...(authRequestId ? { authRequestId } : {}),
generation: ++loginGeneration,
canceled: false,
fallbackPending: false,
fallbackStarted: false,
currentPid: null,
route: 'direct',
fallbackUsed: false,
stages: [],
};
latestLoginAttempt = attempt;
recordVelaAuthStage(
attempt,
{ stage: 'attempt_started', result: 'started' },View on GitHub (pinned to 5be4028344)
Solutions
- Call cancelVelaLogin() (with the expected attempt ids) and wait until isVelaLoginSupervisorSettled() before starting a new attempt.
- Disable the login button while isVelaLoginInFlight() is true.
- Reuse the in-flight attempt's authAttemptId/authRequestId via readVelaLoginAttemptSnapshot() instead of starting a duplicate.
Example fix
// before
const attempt = beginVelaLoginAttempt(authAttemptId, authRequestId);
// after
if (isVelaLoginInFlight()) {
cancelVelaLogin();
await waitFor(() => isVelaLoginSupervisorSettled());
}
const attempt = beginVelaLoginAttempt(authAttemptId, authRequestId); Defensive patterns
Strategy: validation
Validate before calling
import { isVelaLoginInFlight, isVelaLoginSupervisorSettled, cancelVelaLogin } from '../integrations/vela.js';
async function ensureIdleBeforeLogin(): Promise<void> {
if (!isVelaLoginInFlight()) return;
cancelVelaLogin();
// wait for the supervisor to settle (no pending fallback, all children closed)
while (!isVelaLoginSupervisorSettled()) {
await new Promise((r) => setTimeout(r, 20));
}
} Try / catch
try {
return beginVelaLoginAttempt(authAttemptId, authRequestId);
} catch (err) {
if (err instanceof Error && err.message === 'vela login already running') {
return { kind: 'already_running', snapshot: readVelaLoginAttemptSnapshot() };
}
throw err;
} Prevention
- Disable the login button while isVelaLoginInFlight() is true.
- Call cancelVelaLogin() and wait for isVelaLoginSupervisorSettled() before retrying.
- Reuse the in-flight attempt's snapshot instead of starting a duplicate.
When it happens
Trigger: A second login request arrives while the first is still spawning/running or while its proxy fallback is pending. Common from double-clicks on the login button, two browser tabs, or a retry that did not wait for cancelVelaLogin to settle.
Common situations: UI 'Sign in' clicked twice; concurrent tabs/clients both driving /api login; a previous login hung on a transparent-proxy network and the user retried without cancelling; test that starts a second attempt without resetting the supervisor.
Related errors
- vela login attempt is no longer active
- vela login failed to start: ${result.error.message}
- vela login exited before authentication completed (code ${re
- vela login exited before device authorization started (code
- failed to spawn vela login
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/a119c4fbed009412.
Report an issue: GitHub.