{"record":{"id":"7eefc351cb5d6910","repo":"mastra-ai/mastra","slug":"no-credentials","errorCode":null,"errorMessage":"No credentials","messagePattern":"No credentials","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/auth/client.ts","lineNumber":137,"sourceCode":"    if (authHeader?.startsWith('Bearer ')) {\n      _currentToken = authHeader.slice(7);\n    }\n  }\n\n  const response = await fetch(input, init);\n\n  if (response.status !== 401 || !_currentToken) {\n    return response;\n  }\n\n  // Avoid multiple concurrent refreshes\n  if (!_refreshInFlight) {\n    _refreshInFlight = (async () => {\n      try {\n        // Dynamic import to avoid circular dependency\n        const { tryRefreshToken, loadCredentials } = await import('./credentials.js');\n        const creds = await loadCredentials();\n        if (!creds) throw new Error('No credentials');\n\n        const newToken = await tryRefreshToken(creds);\n        if (!newToken) throw new Error('Refresh failed');\n\n        _currentToken = newToken;\n        return newToken;\n      } finally {\n        _refreshInFlight = null;\n      }\n    })();\n  }\n\n  let newToken: string;\n  try {\n    newToken = await _refreshInFlight;\n  } catch {\n    // Refresh failed — return the original 401 response\n    return response;","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/cli/src/commands/auth/client.ts#L119-L155","documentation":"Inside authenticatedFetch's single-flight token refresh, the CLI dynamically imports credentials helpers and calls loadCredentials. If no stored credentials exist at all, it throws 'No credentials', meaning the request cannot be refreshed because there is nothing to refresh from. Callers of platformFetch surface this as an unauthenticated-request failure.","triggerScenarios":"authenticatedFetch detects a 401 (or stale token) and enters the refresh path, but loadCredentials() resolves null because no credentials file exists and no fallback auth was configured.","commonSituations":"Running CLI commands on a fresh machine/CI container without ever running `mastra auth login`; HOME differs so the credentials file path is not found; credentials file deleted by cleanup scripts; non-interactive CI without MASTRA_API_TOKEN.","solutions":["Run `mastra auth login` to create credentials.","Set MASTRA_API_TOKEN in the environment for non-interactive environments.","Verify HOME/XDG paths point to the profile that holds ~/.mastra credentials in CI.","Mount or restore the credentials file in ephemeral CI environments."],"exampleFix":"// before (CI yaml)\n- run: mastra deploys list\n// after\n- run: mastra deploys list\n  env:\n    MASTRA_API_TOKEN: ${{ secrets.MASTRA_API_TOKEN }}","handlingStrategy":"validation","validationCode":"import { existsSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport path from 'node:path';\nconst credsPath = path.join(homedir(), '.mastra', 'credentials.json');\nif (!existsSync(credsPath) && !process.env.MASTRA_API_TOKEN) {\n  throw new Error('No credentials: run `mastra auth login` or set MASTRA_API_TOKEN');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await platformFetch(url, init);\n} catch (err) {\n  if (err instanceof Error && err.message === 'No credentials') {\n    console.error('Authenticate first: `mastra auth login` or set MASTRA_API_TOKEN');\n    return;\n  }\n  throw err;\n}","preventionTips":["In CI, always provide MASTRA_API_TOKEN — never rely on stored credentials files.","Confirm HOME/XDG_DATA_HOME point to the profile containing ~/.mastra credentials in containers.","Run `mastra auth login` once on each machine before scripted use.","Do not clean ~/.mastra in dotfile cleanup scripts without re-authenticating."],"tags":["cli","auth","credentials","refresh"],"backgroundTag":"missing-credentials","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}