mastra-ai/mastra · error
Batch embedder returned no embedding for input text.
Error message
Batch embedder returned no embedding for input text.
What it means
The configured embedder is a batch-capable embedder (branded with `batch: true`), and `#embedOne` dispatched the single text as a one-element array, but the returned embeddings array was empty — no embedding came back for the input. This indicates a misbehaving embedder implementation rather than a configuration problem.
Source
Thrown at packages/core/src/workspace/search/search-engine.ts:687
return 'bm25';
}
throw new Error('No search configuration available. Provide bm25 or vector config.');
}
/**
* Embed a single text, dispatching to the batch path with a one-element array
* when the configured embedder is batch-capable.
*/
async #embedOne(text: string): Promise<number[]> {
if (!this.#vectorConfig) {
throw new Error('Vector configuration is required to embed text.');
}
const { embedder } = this.#vectorConfig;
if (isBatchEmbedder(embedder)) {
const [embedding] = await embedder([text]);
if (!embedding) {
throw new Error('Batch embedder returned no embedding for input text.');
}
return embedding;
}
return embedder(text);
}
/**
* Embed many texts. Uses a single batched call (chunked by `maxBatchSize`)
* when the embedder is batch-capable; otherwise falls back to parallel
* single-text calls.
*/
async #embedAll(texts: string[]): Promise<number[][]> {
if (!this.#vectorConfig) {
throw new Error('Vector configuration is required to embed texts.');
}
if (texts.length === 0) return [];
const { embedder } = this.#vectorConfig;View on GitHub (pinned to 75dd419e61)
Solutions
- Fix the batch embedder implementation so it always returns exactly one embedding per input text, in order (verify the `embedMany` result: `return embeddings`, not a nested/destructured value).
- Add an assertion in your embedder: throw if `embeddings.length !== texts.length`.
- If the provider can silently drop inputs, fall back to a single-text embedder (omit the `batch: true` brand) so each call gets one result.
Example fix
// before — drops texts, returns fewer embeddings
const embedder: BatchEmbedder = Object.assign(
async (texts) => {
const { embeddings } = await embedMany({ model, values: texts.filter(Boolean) });
return embeddings;
},
{ batch: true as const },
);
// after — 1:1 with input, validated
const embedder: BatchEmbedder = Object.assign(
async (texts) => {
const { embeddings } = await embedMany({ model, values: texts });
if (embeddings.length !== texts.length) {
throw new Error('Embedding count mismatch');
}
return embeddings;
},
{ batch: true as const },
); Defensive patterns
Strategy: type-guard
Validate before calling
function assertValidBatchEmbedder(e: Embedder): asserts e is BatchEmbedder {
if (!isBatchEmbedder(e)) return;
// smoke-test in dev: batch embedder must return 1:1 results
}
// at construction:
const probe = await embedder(['ping']);
if (probe.length !== 1) throw new Error('Batch embedder violates 1:1 contract'); Type guard
function isWellFormedBatchEmbedder(e: Embedder): e is BatchEmbedder {
return isBatchEmbedder(e) && typeof e === 'function';
} Try / catch
try {
const vec = await engine.queryEmbedding(text);
} catch (e) {
if (e instanceof Error && e.message.includes('Batch embedder returned no embedding')) {
// rebuild engine with a single-text embedder or fixed batch embedder
} else {
throw e;
}
} Prevention
- Validate custom batch embedders with a probe call at startup (1 input -> 1 output).
- Never filter or reorder inputs inside a batch embedder; preserve input length and order.
- Throw explicitly inside the embedder on provider errors instead of returning short arrays.
- Add a length assertion (`embeddings.length === texts.length`) in the embedder wrapper.
When it happens
Trigger: A `BatchEmbedder` whose implementation returns an array shorter than its input (e.g. `embedMany` result destructured incorrectly, empty array returned for empty/filtered input, provider dropping a text) reached via `embedding(text)` or `queryEmbedding(text)`.
Common situations: Custom embedder wrappers that filter out blank strings and return fewer results; a provider returning zero embeddings on API error without throwing; hand-rolled `Object.assign(fn, { batch: true })` where `fn` doesn't preserve input order/count.
Related errors
- Vector configuration is required to embed text.
- Platform connection response missing DATABASE_URL.
- AGENT_GENERATE_MALFORMED_RESULT
- Invalid model string format: "${config}". Expected format: "
- ${this.constructor.name}: find() requires connect() to adopt
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/22489fcbbd029185.
Report an issue: GitHub.