thedotmack/claude-mem · error · ServerClassifiedProviderError

auth_invalid

auth_invalid

Error message

Anthropic API key not configured

What it means

Thrown by the ClaudeObservationProvider constructor when options.apiKey is falsy. It is a ServerClassifiedProviderError with kind 'auth_invalid', signalling that the Claude (Anthropic) generation provider cannot make authenticated calls. Constructing the provider is the trust boundary — auth is validated up front rather than failing on the first request.

Source

Thrown at src/server/generation/providers/ClaudeObservationProvider.ts:47

  fetchImpl?: typeof fetch;
}

interface AnthropicMessagesResponse {
  content?: Array<{ type?: string; text?: string }>;
  usage?: { input_tokens?: number; output_tokens?: number };
  error?: { type?: string; message?: string };
}

export class ClaudeObservationProvider implements ServerGenerationProvider {
  readonly providerLabel = 'claude' as const;
  private readonly apiKey: string;
  private readonly model: string;
  private readonly maxOutputTokens: number;
  private readonly fetchImpl: typeof fetch;

  constructor(options: ClaudeObservationProviderOptions) {
    if (!options.apiKey) {
      throw new ServerClassifiedProviderError('Anthropic API key not configured', {
        kind: 'auth_invalid',
        cause: new Error('apiKey is required'),
      });
    }
    this.apiKey = options.apiKey;
    this.model = options.model ?? DEFAULT_MODEL;
    this.maxOutputTokens = options.maxOutputTokens ?? 4096;
    this.fetchImpl = options.fetchImpl ?? fetch;
  }

  async generate(
    context: ServerGenerationContext,
    signal?: AbortSignal,
  ): Promise<ServerGenerationResult> {
    const { prompt, skippedAll } = buildServerGenerationPrompt(context);
    if (skippedAll) {
      // All events were scrubbed by privacy stripping. Don't bill the
      // provider — return a synthetic skip response that parser accepts.

View on GitHub (pinned to d768ba3643)

Solutions

  1. Set ANTHROPIC_API_KEY in the environment (or settings) to a valid key before starting the worker/server.
  2. If you intended a different backend, switch the configured provider to gemini/openrouter and supply that provider's key instead.
  3. Verify the settings manager and .env loading actually surface the key (log the resolved length, not the value).
  4. Re-run with a known-good key from the Anthropic console.

Example fix

// before: provider built with no key
new ClaudeObservationProvider({ /* apiKey omitted */ });
// after
new ClaudeObservationProvider({ apiKey: process.env.ANTHROPIC_API_KEY });
// plus: export ANTHROPIC_API_KEY=sk-ant-... before launch
Defensive patterns

Strategy: validation

Validate before calling

function resolveClaudeKey(): string {
  const key = process.env.ANTHROPIC_API_KEY ?? readSetting('anthropicApiKey');
  if (!key || !key.trim()) {
    throw new Error('ANTHROPIC_API_KEY is not set; cannot use the claude provider');
  }
  return key.trim();
}
// pass resolveClaudeKey() into new ClaudeObservationProvider({ apiKey })

Type guard

function hasApiKey(opts: unknown): opts is { apiKey: string } {
  return typeof (opts as { apiKey?: unknown })?.apiKey === 'string'
    && (opts as { apiKey: string }).apiKey.trim().length > 0;
}

Try / catch

try {
  provider = new ClaudeObservationProvider({ apiKey });
} catch (error) {
  if (error instanceof ServerClassifiedProviderError && error.kind === 'auth_invalid') {
    // fall back to a different configured provider, or exit with a clear message
  } else throw error;
}

Prevention

When it happens

Trigger: Instantiating ClaudeObservationProvider with an empty/undefined apiKey; the configured provider is 'claude' but ANTHROPIC_API_KEY is unset; the settings layer resolved the key to an empty string.

Common situations: Operator selects the claude generation provider in config but never exports ANTHROPIC_API_KEY. A .env file isn't loaded. The key was deleted from the secret store. Local-dev bypass masks the missing key until the provider is first built.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12). Data as JSON: /api/errors/65d0b54b4fe87aa9. Report an issue: GitHub.