thedotmack/claude-mem · error · ServerClassifiedProviderError
auth_invalid
auth_invalid
Error message
OpenRouter API key not configured
What it means
Thrown by the OpenRouterObservationProvider constructor when options.apiKey is falsy. It is a ServerClassifiedProviderError with kind 'auth_invalid', so the OpenRouter generation provider refuses to construct without credentials. Model is passed verbatim (per #2393) so arbitrary OpenAI-compatible ids work, but the key itself is mandatory.
Source
Thrown at src/server/generation/providers/OpenRouterObservationProvider.ts:53
interface OpenRouterResponse {
choices?: Array<{ message?: { content?: string } }>;
usage?: { total_tokens?: number };
error?: { code?: string | number; message?: string };
}
export class OpenRouterObservationProvider implements ServerGenerationProvider {
readonly providerLabel = 'openrouter' as const;
private readonly apiKey: string;
private readonly model: string;
private readonly apiUrl: string;
private readonly maxOutputTokens: number;
private readonly siteUrl: string;
private readonly appName: string;
private readonly fetchImpl: typeof fetch;
constructor(options: OpenRouterObservationProviderOptions) {
if (!options.apiKey) {
throw new ServerClassifiedProviderError('OpenRouter API key not configured', {
kind: 'auth_invalid',
cause: new Error('apiKey is required'),
});
}
this.apiKey = options.apiKey;
// Model is passed verbatim so arbitrary OpenAI-compatible ids work. #2393.
this.model = options.model ?? DEFAULT_MODEL;
this.apiUrl = resolveOpenRouterChatCompletionsUrl(options.baseUrl);
this.maxOutputTokens = options.maxOutputTokens ?? 4096;
this.siteUrl = options.siteUrl ?? 'https://github.com/thedotmack/claude-mem';
this.appName = options.appName ?? 'claude-mem';
this.fetchImpl = options.fetchImpl ?? fetch;
}
async generate(
context: ServerGenerationContext,
signal?: AbortSignal,
): Promise<ServerGenerationResult> {View on GitHub (pinned to d768ba3643)
Solutions
- Set OPENROUTER_API_KEY (or the configured setting) to a valid key from openrouter.ai before launch.
- Switch providers if openrouter was selected by mistake.
- Verify the settings/env layer resolves the key (check length only).
- Re-run after fixing config.
Example fix
// before: no key supplied
new OpenRouterObservationProvider({ /* apiKey omitted */ });
// after
new OpenRouterObservationProvider({ apiKey: process.env.OPENROUTER_API_KEY });
// plus: export OPENROUTER_API_KEY=sk-or-... before launch Defensive patterns
Strategy: validation
Validate before calling
function resolveOpenRouterKey(): string {
const key = process.env.OPENROUTER_API_KEY ?? readSetting('openRouterApiKey');
if (!key || !key.trim()) {
throw new Error('OPENROUTER_API_KEY is not set; cannot use the openrouter provider');
}
return key.trim();
} 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 OpenRouterObservationProvider({ apiKey });
} catch (error) {
if (error instanceof ServerClassifiedProviderError && error.kind === 'auth_invalid') {
// choose another provider or exit with guidance
} else throw error;
} Prevention
- Validate required keys at startup and fail fast with a provider-specific message.
- Load .env consistently across environments.
- Store keys in a secret manager and detect revocation via a cheap auth probe.
When it happens
Trigger: Instantiating OpenRouterObservationProvider with an empty/undefined apiKey; the configured provider is 'openrouter' but the key setting is unset; the settings layer resolved the key to an empty string.
Common situations: Operator selects openrouter but never exports OPENROUTER_API_KEY. A .env file isn't loaded. The key was revoked at openrouter.ai. Local-dev bypass masks the gap until construction.
Related errors
- auth_invalid
- auth_invalid
- Unknown Claude model: ${options.model}. Allowed: ${[...allow
- parse_error
- API key is scoped to a different project
AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12).
Data as JSON: /api/errors/ba9457800973d837.
Report an issue: GitHub.