thedotmack/claude-mem · error · ServerClassifiedProviderError

classifyHttpProviderError

Error message

classifyHttpProviderError({ cause: err, providerLabel: 'OpenRouter' })

What it means

OpenRouterObservationProvider.generate wraps the chat-completions call; any rejection from postChatCompletion (no HTTP response received) is rethrown via classifyHttpProviderError({ cause, providerLabel: 'OpenRouter' }). This is a transport-level failure: the request to openrouter.ai never completed at the HTTP layer.

Solutions

  1. Verify connectivity to openrouter.ai from the runtime.
  2. Check proxy/firewall/DNS configuration; test with curl.
  3. Increase the timeout / use a longer-lived AbortSignal for large generations.
  4. Retry with backoff for transient network causes.

Example fix

// before
const r = await openRouterProvider.generate(prompt, signal);
// after
try { const r = await openRouterProvider.generate(prompt, signal); }
catch (e) { if (e.kind === 'retryable') return retryWithBackoff(); throw e; }
Defensive patterns

Strategy: try-catch

Type guard

function isNetworkError(e: unknown): e is TypeError {
  return e instanceof TypeError && /fetch|network/i.test(e.message);
}

Try / catch

try {
  result = await openRouterProvider.generate(prompt, signal);
} catch (e) {
  if (e.kind === 'retryable') return retryWithBackoff(() => openRouterProvider.generate(prompt, signal));
  throw e;
}

Prevention

When it happens

Trigger: `postChatCompletion()` rejects: DNS failure, connection refused/reset, TLS error, timeout, or AbortSignal fired — caught at OpenRouterObservationProvider.ts:84-91.

Common situations: Outage or brownout of openrouter.ai, DNS/proxy issues, network restrictions in CI, request timeouts on very large completions, VPN interference.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17). Data as JSON: /api/errors/e86bb0525c991db3. Report an issue: GitHub.

Appendix: source

Thrown at src/server/generation/providers/OpenRouterObservationProvider.ts:88

  async generate(
    context: ServerGenerationContext,
    signal?: AbortSignal,
  ): Promise<ServerGenerationResult> {
    const { prompt, skippedAll } = buildServerGenerationPrompt(context);
    if (skippedAll) {
      return {
        rawText: '<skip_summary reason="all_events_private" />',
        providerLabel: this.providerLabel,
        modelId: this.model,
      };
    }

    let response: Response;
    try {
      response = await this.postChatCompletion(prompt, signal);
    } catch (networkError) {
      const err = networkError instanceof Error ? networkError : new Error(String(networkError));
      throw classifyHttpProviderError({
        cause: err,
        providerLabel: 'OpenRouter',
      });
    }

    if (!response.ok) {
      const bodyText = await safeReadBody(response);
      throw classifyHttpProviderError({
        status: response.status,
        bodyText,
        headers: response.headers,
        cause: new Error(`OpenRouter API error: ${response.status} - ${bodyText}`),
        providerLabel: 'OpenRouter',
      });
    }

    let data: OpenRouterResponse;
    try {

View on GitHub (pinned to d8bc9755e7)