Mintplex-Labs/anything-llm · error · Error
Mistral Failed to embed: ${error.message}
Error message
Mistral Failed to embed: ${error.message} What it means
Thrown in the embedChunks catch block wrapping the entire embeddings.create call. Any rejection — network error, non-2xx HTTP, the explicit 'empty embeddings' throw above, or an SDK parse failure — is caught, logged to console.error, and re-thrown as 'Mistral Failed to embed: <original message>'. It is the single escape hatch for all Mistral embedding failures.
Source
Thrown at server/utils/EmbeddingEngines/mistral/index.js:34
Array.isArray(textInput) ? textInput : [textInput]
);
return result?.[0] || [];
}
async embedChunks(textChunks = []) {
try {
const response = await this.openai.embeddings.create({
model: this.model,
input: textChunks,
encoding_format: "float",
});
const embeddings = response?.data?.map((emb) => emb.embedding) || [];
if (embeddings.length === 0)
throw new Error("Mistral returned empty embeddings for batch");
return embeddings;
} catch (error) {
console.error("Failed to get embeddings from Mistral.", error.message);
throw new Error(`Mistral Failed to embed: ${error.message}`);
}
}
}
module.exports = {
MistralEmbedder,
};
View on GitHub (pinned to 526360e320)
Solutions
- Read error.message in the thrown string: 401 -> rotate/fix MISTRAL_API_KEY; 429 -> reduce batch size / add backoff; 5xx -> retry after a short delay
- If the message is 'empty embeddings for batch', follow error 330 fixes (check EMBEDDING_MODEL_PREF is an embedding model)
- curl api.mistral.ai/v1/embeddings directly to isolate SDK vs network vs provider
- Add retry with exponential backoff in the caller for transient 5xx/429
Example fix
// before
// caller does no retry, single 429 aborts the whole doc ingest
// after
// wrap the embed call with a bounded retry on transient errors
for (let attempt = 0; attempt < 3; attempt++) {
try { return await embedder.embedChunks(chunks); }
catch (e) {
if (attempt === 2 || /401|empty embeddings/.test(e.message)) throw e;
}
} Defensive patterns
Strategy: retry
Validate before calling
// pre-flight: key valid and not rate-limited on a tiny call
async function mistralReachable(openai, model) {
await openai.embeddings.create({ model, input: 'ping' });
} Type guard
function isMistralEmbedError(e) {
return e instanceof Error && /Mistral Failed to embed/.test(e.message);
} Try / catch
async function embedWithRetry(embedder, chunks, attempts = 3) {
for (let i = 0; i < attempts; i++) {
try { return await embedder.embedChunks(chunks); }
catch (e) {
const transient = /429|5\d\d|Failed to fetch|ETIMEDOUT/.test(e.message);
if (!transient || i === attempts - 1) throw e;
await new Promise(r => setTimeout(r, 2 ** i * 1000));
}
}
} Prevention
- Add exponential backoff in the caller for 429/5xx.
- Keep batches within Mistral's per-request token limits.
- Rotate expired keys promptly.
When it happens
Trigger: embeddings.create rejects: 401 (bad/expired MISTRAL_API_KEY); 429 rate limit; 5xx Mistral outage; the inner 'Mistral returned empty embeddings for batch' throw; network timeout; SDK unable to parse a non-JSON gateway response.
Common situations: Key expired or revoked; hitting Mistral rate limits on a large batch; transient 5xx; running behind a corporate proxy that returns an HTML error page; deprecated model returning an API error.
Related errors
- OpenAI Failed to embed: ${error}
- No Mistral API key was set.
- Mistral returned empty embeddings for batch
- ${res.reason}
- e.message
AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13).
Data as JSON: /api/errors/b15be9607dc858aa.
Report an issue: GitHub.