{"record":{"id":"9f979d976ecdd57f","repo":"windmill-labs/windmill","slug":"not-logged-in-please-run-wmill-workspace-add-fi","errorCode":null,"errorMessage":"Not logged in. Please run 'wmill workspace add' first.","messagePattern":"Not logged in\\. Please run 'wmill workspace add' first\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/workspace/fork.ts","lineNumber":137,"sourceCode":"  if (!workspace) {\n    throw new Error(\"Could not resolve workspace from branch name. Make sure you are in a git repo to use workspace forks\");\n  }\n\n  log.info(`You are forking workspace (${workspace.workspaceId})`)\n\n  if (opts.workspace) {\n    log.info(\n      colors.red.bold(\n        \"! Workspace needs to be specified as positional argument, not as option.\"\n      )\n    );\n    return;\n  }\n\n  const token = workspace.token;\n\n  if (!token) {\n    throw new Error(\"Not logged in. Please run 'wmill workspace add' first.\");\n  }\n\n  const remote = workspace.remote\n  setClient(\n    token,\n    remote.endsWith(\"/\") ? remote.substring(0, remote.length - 1) : remote\n  );\n\n  // Default the fork's display name to \"<parent>'s fork\", using the parent\n  // workspace's actual name (fall back to the local profile name / id if the\n  // lookup fails). It's only a default — always overridable.\n  let parentName = workspace.name;\n  try {\n    const fetched = await wmill.getWorkspaceName({ workspace: workspace.workspaceId });\n    if (fetched) parentName = fetched;\n  } catch {\n    // Non-fatal: keep the local profile name / id as the fallback.\n  }","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/cli/src/commands/workspace/fork.ts#L119-L155","documentation":"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.","triggerScenarios":"Workspace entry in wmill.yaml/config lacks a token field — e.g. workspace added without a token, token removed, or config edited by hand.","commonSituations":"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.","solutions":["Re-add the workspace with a token: `wmill workspace add <remote> <name> <token>`","Generate a new API token in the Windmill UI (User settings > Tokens) and update the workspace entry","Verify with `wmill workspace list` / inspect wmill.yaml that the target workspace has a token"],"exampleFix":"// before\nwmill workspace add https://app.windmill.dev prod  # no token supplied\n// after\nwmill workspace add https://app.windmill.dev prod <API_TOKEN>","handlingStrategy":"validation","validationCode":"const ws = config.workspaces?.find(w => w.gitBranch === currentBranch);\nif (ws && !ws.token) {\n  throw new Error(`Workspace '${ws.name}' has no token. Run 'wmill workspace add <remote> <name> <token>'.`);\n}\nawait createWorkspaceFork(opts, name);","typeGuard":"function hasToken(ws: { token?: string } | undefined): ws is { token: string } & { token?: undefined } extends never ? never : typeof ws extends undefined ? false : true {\n  return !!ws && typeof ws.token === 'string' && ws.token.length > 0;\n}","tryCatchPattern":"try {\n  await createWorkspaceFork(opts, name);\n} catch (e) {\n  if ((e as Error).message.includes(\"Not logged in. Please run 'wmill workspace add'\")) {\n    console.error('Re-add the workspace with a token: wmill workspace add <remote> <name> <token>');\n  } else throw e;\n}","preventionTips":["Always supply the token when running `wmill workspace add`","Don't hand-edit wmill.yaml to strip token fields","Check `wmill workspace list` shows the workspace as authenticated before scripted forks"],"tags":["auth","token","cli"],"backgroundTag":"missing-auth-token","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}