{"record":{"id":"42e7f81f81e8228f","repo":"ruvnet/ruflo","slug":"not-logged-in-for-profile-profile-run-rufl","errorCode":null,"errorMessage":"not logged in for profile \"${profile}\" — run: ruflo auth login --profile ${profile}","messagePattern":"not logged in for profile \"(.+?)\" — run: ruflo auth login --profile (.+?)","errorType":"exception","errorClass":"NotLoggedInError","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/auth/client.ts","lineNumber":239,"sourceCode":"      throw new Error(`Cognitum auth service returned an unexpected response: ${e.message}`);\n    }\n    throw e;\n  }\n}\n\n/**\n * Returns an access token suitable for an authenticated call.\n *\n * Fast path: a process-memory token with more than one minute remaining.\n * Slow path: load the profile's refresh token from the OS keychain, perform\n * one refresh, persist a rotated refresh token BEFORE exposing the new access\n * token, then update metadata and the process cache. Refresh is deliberately\n * demand-driven: offline-safe commands such as plain `auth status` never call\n * this function and therefore never create background traffic or retry loops.\n */\nexport async function getValidAccessToken(profileName = 'default'): Promise<string> {\n  const profile = getProfile(profileName);\n  if (!profile) throw new NotLoggedInError(profileName);\n\n  const scopesWithoutConsent = profile.scopes.filter((scope) => {\n    const domain = domainForScope(scope);\n    return domain !== undefined && !hasConsent(domain);\n  });\n  if (scopesWithoutConsent.length > 0) {\n    throw new ScopeConsentMismatchError(profileName, scopesWithoutConsent);\n  }\n\n  const cached = getSessionToken(profileName, ACCESS_TOKEN_REFRESH_WINDOW_MS);\n  if (cached) return cached;\n  if (!profile.keychainRef) throw new SessionOnlyExpiredError(profileName);\n\n  const sec = await loadSecurityOAuth();\n  const keychain = await sec.createKeychainAdapter();\n  const refreshTokenValue = await keychain.getSecret(KEYCHAIN_SERVICE, profile.keychainRef);\n  if (!refreshTokenValue) throw new SessionOnlyExpiredError(profileName);\n","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/auth/client.ts#L221-L257","documentation":"getValidAccessToken(profileName) throws NotLoggedInError when getProfile(profileName) returns nothing — there is no stored auth profile for that name. The message includes the exact remediation command. Profiles are created by `ruflo auth login`; asking for a profile that never logged in (or a typo'd name) hits this immediately, before any network traffic.","triggerScenarios":"Calling getValidAccessToken('work') when only the 'default' profile exists; calling with the default when no login ever happened; a typo or case-mismatched profile name ('Default' vs 'default'); the profile state file was deleted or never created on a fresh machine/CI container.","commonSituations":"New machine or CI runner with no prior `ruflo auth login`; scripts hard-coding a profile name that doesn't match what the user created; state directory removed during cleanup (~/.claude-flow or equivalent wiped); switching between accounts and forgetting to log in under the new profile.","solutions":["Run the command from the message: ruflo auth login --profile <profile>","Check which profiles exist first: ruflo auth status","If the name was a typo, call getValidAccessToken with the exact profile name you logged in as","On ephemeral CI machines, perform a login step (e.g. --token-stdin) before any authenticated command"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Cheap pre-check: run `ruflo auth status` (offline-safe) and assert the profile is listed\nconst status = await runRuflo(['auth', 'status', '--json']);\nif (!status.profiles.includes(profileName)) await runRuflo(['auth', 'login', '--profile', profileName]);","typeGuard":"import { NotLoggedInError } from '@claude-flow/cli/dist/auth/client.js';\nfunction isNotLoggedIn(e: unknown): e is NotLoggedInError {\n  return e instanceof Error && e.name === 'NotLoggedInError';\n}","tryCatchPattern":"try {\n  token = await getValidAccessToken(profileName);\n} catch (e) {\n  if (isNotLoggedIn(e)) {\n    console.error(e.message); // already contains the exact login command\n    process.exit(3);\n  }\n  throw e;\n}","preventionTips":["Run `ruflo auth status` at session start on CI/new machines","Treat profile names as config: validate them once at startup","Catch by error name (NotLoggedInError), not by parsing the human message"],"tags":["auth","oauth","profile","cli"],"backgroundTag":"not-logged-in","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}