Mintplex-Labs/anything-llm · error · Error
OpenRouter Failed to embed: ${error}
Error message
OpenRouter Failed to embed: ${error} What it means
Thrown at the end of OpenRouterEmbedder.embedChunks after all parallel embedding batches settle. Each batch runs as a self-catching Promise that resolves with {data:[], error} on failure instead of rejecting, so Promise.all never rejects. The collected unique errors are joined into one string and thrown here only if at least one batch failed. The wrapped error string is already formatted like '[429]: <message>' because the per-batch catch normalizes e.type and e.message from the OpenAI SDK response shape.
Source
Thrown at server/utils/EmbeddingEngines/openRouter/index.js:94
.flat();
if (errors.length > 0) {
let uniqueErrors = new Set();
errors.map((error) =>
uniqueErrors.add(`[${error.type}]: ${error.message}`)
);
return {
data: [],
error: Array.from(uniqueErrors).join(", "),
};
}
return {
data: results.map((res) => res?.data || []).flat(),
error: null,
};
});
if (!!error) throw new Error(`OpenRouter Failed to embed: ${error}`);
return data.length > 0 &&
data.every((embd) => embd.hasOwnProperty("embedding"))
? data.map((embd) => embd.embedding)
: null;
}
}
async function fetchOpenRouterEmbeddingModels() {
return await fetch(`https://openrouter.ai/api/v1/embeddings/models`, {
method: "GET",
headers: { "Content-Type": "application/json" },
})
.then((res) => res.json())
.then(({ data = [] }) => {
const models = {};
data.forEach((model) => {
models[model.id] = {
id: model.id,View on GitHub (pinned to 526360e320)
Solutions
- Check the wrapped error string — the [type] prefix identifies the cause: [429] = rate limit (wait and retry / upgrade tier), [401] = bad key, [failed_to_embed] = network/model issue.
- Verify OPENROUTER_API_KEY is set and valid by calling the OpenRouter embeddings models endpoint directly.
- Confirm EMBEDDING_MODEL_PREF is a valid OpenRouter embedding model id (list via fetchOpenRouterEmbeddingModels).
- For 429s, reduce workspace embed batch size or add delay/backoff; OpenRouter free tier has strict RPM limits.
- Ensure no single input chunk exceeds 8191 tokens (the embeddingMaxChunkLength) — pre-split oversized chunks before embedding.
Example fix
// before: oversized chunks cause model rejection await openRouterEmbedder.embedChunks(hugeDocumentChunks); // after: pre-split chunks under the token limit before embedding const MAX_TOKENS = 8000; // stay below 8191 const safeChunks = hugeDocumentChunks.flatMap(c => splitIfTooLong(c, MAX_TOKENS)); await openRouterEmbedder.embedChunks(safeChunks);
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate model and key before embedding
const { fetchOpenRouterEmbeddingModels } = require("./openRouter");
const models = await fetchOpenRouterEmbeddingModels();
if (!models[process.env.EMBEDDING_MODEL_PREF]) {
throw new Error(`Unknown OpenRouter embedding model: ${process.env.EMBEDDING_MODEL_PREF}`);
}
if (!process.env.OPENROUTER_API_KEY) {
throw new Error('OPENROUTER_API_KEY is not set');
} Type guard
/** @param {unknown} e */
function isOpenRouterEmbedError(e) {
return e instanceof Error && /^OpenRouter Failed to embed:/.test(e.message);
} Try / catch
try {
const vectors = await embedder.embedChunks(chunks);
if (!vectors) throw new Error('Embedding produced no vectors');
} catch (e) {
if (/\[429\]/.test(e.message)) { /* backoff and retry */ }
else if (/\[401\]|\[403\]/.test(e.message)) throw new Error('Bad OpenRouter API key');
else throw e;
} Prevention
- Pre-validate EMBEDDING_MODEL_PREF against fetchOpenRouterEmbeddingModels before bulk embedding.
- Keep chunks under the 8191-token embeddingMaxChunkLength by pre-splitting.
- For large workspaces, throttle to avoid OpenRouter free-tier RPM limits.
- Log the wrapped [type] prefix to classify failures for alerting.
When it happens
Trigger: Calling embedChunks/embedTextInput with an invalid or unset OPENROUTER_API_KEY, a non-existent EMBEDDING_MODEL_PREF, input text exceeding the 8191-token embeddingMaxChunkLength per chunk, OpenRouter HTTP rate limits (429), upstream provider outages, or network failures during the embeddings.create call. Because batches of up to maxConcurrentChunks (500) are fired in parallel, a single failing batch aborts the whole sequence.
Common situations: Switching embedding models without updating EMBEDDING_MODEL_PREF to a valid OpenRouter embedding model id; hitting OpenRouter free-tier rate limits when embedding a large workspace; passing oversized document chunks that exceed the model context window; API key rotated in the provider but not in the AnythingLLM env; transient OpenRouter routing errors to the backing model provider.
Related errors
- Could not find indexes.
- ${e.message}
- OMLX:cacheContextWindows - ${res.statusText}
- No OpenRouter API key was set.
- OpenRouter chat: ${this.model} is not valid for chat complet
AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13).
Data as JSON: /api/errors/11ab5ed75d4432a0.
Report an issue: GitHub.