{"record":{"id":"db452724a0536940","repo":"rohitg00/agentmemory","slug":"voyage-embedding-failed-response-status-er","errorCode":null,"errorMessage":"Voyage embedding failed (${response.status}): ${err}","messagePattern":"Voyage embedding failed \\((.+?)\\): (.+?)","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/providers/embedding/voyage.ts","lineNumber":38,"sourceCode":"  }\n\n  async embedBatch(texts: string[]): Promise<Float32Array[]> {\n    const response = await fetchWithTimeout(API_URL, {\n      method: \"POST\",\n      headers: {\n        Authorization: `Bearer ${this.apiKey}`,\n        \"Content-Type\": \"application/json\",\n      },\n      body: JSON.stringify({\n        model: \"voyage-code-3\",\n        input: texts,\n        input_type: \"document\",\n      }),\n    });\n\n    if (!response.ok) {\n      const err = await response.text();\n      throw new Error(`Voyage embedding failed (${response.status}): ${err}`);\n    }\n\n    const data = (await response.json()) as {\n      data: Array<{ embedding: number[] }>;\n    };\n\n    return data.data.map((d) => new Float32Array(d.embedding));\n  }\n}\n","sourceCodeStart":20,"sourceCodeEnd":48,"githubUrl":"https://github.com/rohitg00/agentmemory/blob/e04ba88819c365c9acf9d6661ea802143e728bd6/src/providers/embedding/voyage.ts#L20-L48","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nawait provider.embedBatch([veryLongDoc]); // 400: exceeds token limit\n// after\nconst chunks = splitByTokens(veryLongDoc, 4000);\nconst vectors = await provider.embedBatch(chunks);","handlingStrategy":"retry","validationCode":"const MAX_TOKENS = 4000;\nconst safeTexts = texts.map(t => t.length > 16000 ? truncate(t) : t); // coarse guard\nif (safeTexts.length === 0) throw new Error('embedBatch called with empty input');","typeGuard":"const isVoyageHttpError = (err: unknown): err is Error & { status?: number } => {\n  const m = String((err as Error)?.message).match(/Voyage embedding failed \\((\\d+)\\)/);\n  return !!m && ((err as Error).status = Number(m[1]), true);\n};","tryCatchPattern":"try {\n  return await provider.embedBatch(texts);\n} catch (err) {\n  if (isVoyageHttpError(err)) {\n    if (err.status === 429 || err.status >= 500) return withBackoff(() => provider.embedBatch(texts));\n    if (err.status === 400) return provider.embedBatch(texts.map(chunkText));\n    if (err.status === 401) throw new Error('Fix VOYAGE_API_KEY');\n  }\n  throw err;\n}","preventionTips":["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"],"tags":["voyage","http-error","network","embedding"],"backgroundTag":"upstream-http-error","analyzedSha":"e04ba88819c365c9acf9d6661ea802143e728bd6","analyzedAt":"2026-08-30T01:07:40.754Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}