rohitg00/agentmemory · error · Error
Voyage embedding failed (${response.status}): ${err}
Error message
Voyage embedding failed (${response.status}): ${err} What it means
The Voyage AI embeddings API (POST /v1/embeddings with input_type) returned a non-2xx status. embedBatch captures the response body and throws it with the status code, exposing Voyage-side validation, auth, or quota failures.
Source
Thrown at src/providers/embedding/voyage.ts:38
}
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: "voyage-code-3",
input: texts,
input_type: "document",
}),
});
if (!response.ok) {
const err = await response.text();
throw new Error(`Voyage 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
- Read the status: 401 -> fix key; 400 -> check model id and input length; 429 -> back off and shrink batches
- Split large texts/batches to respect Voyage token and rate limits
- Confirm no proxy/interceptor removes the Authorization header
- Add retry with backoff for 429/5xx
- Fall back to another provider via createFallbackProvider for resilience
Example fix
// before await provider.embedBatch([veryLongDoc]); // 400: exceeds token limit // after const chunks = splitByTokens(veryLongDoc, 4000); const vectors = await provider.embedBatch(chunks);
Defensive patterns
Strategy: retry
Validate before calling
const MAX_TOKENS = 4000;
const safeTexts = texts.map(t => t.length > 16000 ? truncate(t) : t); // coarse guard
if (safeTexts.length === 0) throw new Error('embedBatch called with empty input'); Type guard
const isVoyageHttpError = (err: unknown): err is Error & { status?: number } => {
const m = String((err as Error)?.message).match(/Voyage embedding failed \((\d+)\)/);
return !!m && ((err as Error).status = Number(m[1]), true);
}; Try / catch
try {
return await provider.embedBatch(texts);
} catch (err) {
if (isVoyageHttpError(err)) {
if (err.status === 429 || err.status >= 500) return withBackoff(() => provider.embedBatch(texts));
if (err.status === 400) return provider.embedBatch(texts.map(chunkText));
if (err.status === 401) throw new Error('Fix VOYAGE_API_KEY');
}
throw err;
} Prevention
- Chunk long documents below Voyage's token cap before embedding
- Throttle bulk backfills; respect rate limits
- Keep texts non-empty and batch sizes moderate
- Test the key with a single embed() before large jobs
When it happens
Trigger: Calling embed()/embedBatch() when Voyage rejects the request: 401 invalid VOYAGE_API_KEY, 400 invalid model or input exceeding token limits, 429 rate limit, 5xx outage.
Common situations: Free-tier quota exhausted during bulk backfill; model id typo (voyage-3 vs voyage-2); oversized batch or single text above the token cap; corporate proxy stripping the Authorization header.
Related errors
- OpenAI embedding failed (${response.status}): ${err}
- OpenRouter embedding failed (${response.status}): ${err}
- POST ${url} failed: ${res.status} ${res.statusText}${suffix}
- ${init?.method || "GET"} ${path} -> ${res.status} ${res.stat
- Cohere embedding failed (${response.status}): ${err}
AI-assisted analysis of rohitg00/agentmemory@e04ba88819 (2026-08-30).
Data as JSON: /api/errors/db452724a0536940.
Report an issue: GitHub.