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
- Inspect status in the message: 401 -> fix key; 402 -> add credits; 429 -> backoff/reduce batch size
- Confirm the configured OPENROUTER_EMBEDDING_MODEL id actually supports the embeddings endpoint on OpenRouter
- Test the same request with curl to isolate agentmemory from network/proxy issues
- Add retry with exponential backoff for transient 429/5xx
- 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
- Use only model ids confirmed to support the OpenRouter embeddings route
- Keep account credits topped up (402 fails fast)
- Wire createFallbackProvider with a second embedding vendor
- Back off exponentially on 429 and batch conservatively
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
- OpenAI embedding failed (${response.status}): ${err}
- Voyage embedding failed (${response.status}): ${err}
- ${this.name} API error (${response.status}): ${text}
- POST ${url} failed: ${res.status} ${res.statusText}${suffix}
- ${init?.method || "GET"} ${path} -> ${res.status} ${res.stat
AI-assisted analysis of rohitg00/agentmemory@e04ba88819 (2026-08-30).
Data as JSON: /api/errors/b1b71e4618c29fe5.
Report an issue: GitHub.