rohitg00/agentmemory · error · Error

OpenRouter embedding failed (${response.status}): ${err}

Error message

OpenRouter embedding failed (${response.status}): ${err}

What it means

The OpenRouter embeddings endpoint responded with a non-2xx status. embedBatch reads the response text and throws it prefixed with the HTTP status, so provider-side failures (auth, model availability, credits, rate limits) reach the caller verbatim.

Source

Thrown at src/providers/embedding/openrouter.ts:47

    return result;
  }

  async embedBatch(texts: string[]): Promise<Float32Array[]> {
    const response = await fetchWithTimeout(API_URL, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${this.apiKey}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        model: this.model,
        input: texts,
      }),
    });

    if (!response.ok) {
      const err = await response.text();
      throw new Error(
        `OpenRouter embedding failed (${response.status}): ${err}`,
      );
    }

    const data = (await response.json()) as {
      data: Array<{ embedding: number[] }>;
    };

    return data.data.map((d) => new Float32Array(d.embedding));
  }
}

View on GitHub (pinned to e04ba88819)

Solutions

  1. Inspect status in the message: 401 -> fix key; 402 -> add credits; 429 -> backoff/reduce batch size
  2. Confirm the configured OPENROUTER_EMBEDDING_MODEL id actually supports the embeddings endpoint on OpenRouter
  3. Test the same request with curl to isolate agentmemory from network/proxy issues
  4. Add retry with exponential backoff for transient 429/5xx
  5. Fall back to another embedding provider via createFallbackProvider if OpenRouter is chronically unavailable

Example fix

// before
const provider = new OpenRouterEmbeddingProvider(key);
await provider.embed(text); // 404: model lacks embeddings route
// after: use an embeddings-capable model
// export OPENROUTER_EMBEDDING_MODEL=openai/text-embedding-3-small
Defensive patterns

Strategy: fallback

Validate before calling

const key = process.env.OPENROUTER_API_KEY;
if (!key) throw new Error('OPENROUTER_API_KEY not set');
const model = process.env.OPENROUTER_EMBEDDING_MODEL;
const EMBED_CAPABLE = [/^openai\/text-embedding/, /^google\/text-embedding/];
if (model && !EMBED_CAPABLE.some(re => re.test(model))) console.warn(`Model ${model} may not support OpenRouter embeddings`);

Type guard

const isRateLimit = (err: unknown): boolean => /OpenRouter embedding failed \((429|5\d\d)\)/.test(String((err as Error)?.message));

Try / catch

try {
  return await openrouterProvider.embedBatch(texts);
} catch (err) {
  if (isRateLimit(err)) {
    await sleep(expoBackoff(attempt++));
    return openrouterProvider.embedBatch(texts);
  }
  if (/embedding failed \(40[124]\)/.test(String((err as Error).message))) {
    return fallbackProvider.embedBatch(texts); // switch to openai/voyage
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling embed()/embedBatch() when OpenRouter rejects the request: 401 invalid OPENROUTER_API_KEY, 404 model not available for embeddings on OpenRouter, 402 insufficient credits, 429 rate limit, 5xx upstream outage.

Common situations: Chat-only model ids used as embedding models (many OpenRouter models don't support the embeddings route); free-tier credit exhaustion; key revoked; OPENROUTER_EMBEDDING_MODEL set to an id OpenRouter cannot serve; regional blocks.

Related errors


AI-assisted analysis of rohitg00/agentmemory@e04ba88819 (2026-08-30). Data as JSON: /api/errors/b1b71e4618c29fe5. Report an issue: GitHub.