windmill-labs/windmill · error · Error

Not logged in. Please run 'wmill workspace add' first.

Error message

Not logged in. Please run 'wmill workspace add' first.

What it means

The resolved parent workspace has no stored token, meaning the CLI has credentials for the workspace profile but no API token (or the profile is only partially configured). Forking calls the Windmill API on behalf of the parent workspace, so authentication is mandatory. The CLI throws before making any request.

Source

Thrown at cli/src/commands/workspace/fork.ts:137

  if (!workspace) {
    throw new Error("Could not resolve workspace from branch name. Make sure you are in a git repo to use workspace forks");
  }

  log.info(`You are forking workspace (${workspace.workspaceId})`)

  if (opts.workspace) {
    log.info(
      colors.red.bold(
        "! Workspace needs to be specified as positional argument, not as option."
      )
    );
    return;
  }

  const token = workspace.token;

  if (!token) {
    throw new Error("Not logged in. Please run 'wmill workspace add' first.");
  }

  const remote = workspace.remote
  setClient(
    token,
    remote.endsWith("/") ? remote.substring(0, remote.length - 1) : remote
  );

  // Default the fork's display name to "<parent>'s fork", using the parent
  // workspace's actual name (fall back to the local profile name / id if the
  // lookup fails). It's only a default — always overridable.
  let parentName = workspace.name;
  try {
    const fetched = await wmill.getWorkspaceName({ workspace: workspace.workspaceId });
    if (fetched) parentName = fetched;
  } catch {
    // Non-fatal: keep the local profile name / id as the fallback.
  }

View on GitHub (pinned to e474e8803c)

Solutions

  1. Re-add the workspace with a token: `wmill workspace add <remote> <name> <token>`
  2. Generate a new API token in the Windmill UI (User settings > Tokens) and update the workspace entry
  3. Verify with `wmill workspace list` / inspect wmill.yaml that the target workspace has a token

Example fix

// before
wmill workspace add https://app.windmill.dev prod  # no token supplied
// after
wmill workspace add https://app.windmill.dev prod <API_TOKEN>
Defensive patterns

Strategy: validation

Validate before calling

const ws = config.workspaces?.find(w => w.gitBranch === currentBranch);
if (ws && !ws.token) {
  throw new Error(`Workspace '${ws.name}' has no token. Run 'wmill workspace add <remote> <name> <token>'.`);
}
await createWorkspaceFork(opts, name);

Type guard

function hasToken(ws: { token?: string } | undefined): ws is { token: string } & { token?: undefined } extends never ? never : typeof ws extends undefined ? false : true {
  return !!ws && typeof ws.token === 'string' && ws.token.length > 0;
}

Try / catch

try {
  await createWorkspaceFork(opts, name);
} catch (e) {
  if ((e as Error).message.includes("Not logged in. Please run 'wmill workspace add'")) {
    console.error('Re-add the workspace with a token: wmill workspace add <remote> <name> <token>');
  } else throw e;
}

Prevention

When it happens

Trigger: Workspace entry in wmill.yaml/config lacks a token field — e.g. workspace added without a token, token removed, or config edited by hand.

Common situations: Running `wmill workspace add` interactively and skipping the token prompt; copying a workspace entry from a teammate without their token; token cleared by a config cleanup; using a workspace name that shadows a logged-in one.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/9f979d976ecdd57f. Report an issue: GitHub.