abhigyanpatwari/GitNexus · error · HttpEmbeddingError
Embedding dimension mismatch: endpoint returned ${vec.length
Error message
Embedding dimension mismatch: endpoint returned ${vec.length}d vector, but expected ${expected}d. ${hint} What it means
An HttpEmbeddingError thrown by httpEmbed when an embedding vector's width does not match the expected dimension (config.dimensions ?? DEFAULT_DIMS, i.e. GITNEXUS_EMBEDDING_DIMS or 384). It is thrown outside the retry loop deliberately: a width mismatch is an operator configuration error, not an endpoint fault, so retrying cannot change the answer and routing it through the retry loop would unfairly penalize a healthy endpoint via the shared circuit breaker (#2790). The message names both widths and emits an actionable config hint.
Source
Thrown at gitnexus/src/core/embeddings/http-client.ts:618
// into the FLOAT[N] column which would cause a cryptic Kuzu error.
//
// Unlike the cardinality check this one stays *outside* the retry loop,
// deliberately. The expected width is `config.dimensions ?? DEFAULT_DIMS`
// (GITNEXUS_EMBEDDING_DIMS), which is NOT the `dimensions` value
// `httpEmbedBatch` receives — that is `config.requestDimensions`, which
// `GITNEXUS_EMBEDDING_REQUEST_DIMS` can set to a different number or to
// `undefined` (`omit`). More importantly a width mismatch is an operator
// *configuration* error, not an endpoint fault: retrying it three times
// can never change the answer, and routing it through the retry loop
// would count a healthy endpoint's responses toward the shared circuit
// breaker. The message is an actionable config hint, so it is terminal
// on the first attempt by design (#2790).
const expected = config.dimensions ?? DEFAULT_DIMS;
if (vec.length !== expected) {
const hint = config.dimensions
? 'Update GITNEXUS_EMBEDDING_DIMS to match your model output.'
: `Set GITNEXUS_EMBEDDING_DIMS=${vec.length} to match your model output.`;
throw new HttpEmbeddingError(
`Embedding dimension mismatch: endpoint returned ${vec.length}d vector, ` +
`but expected ${expected}d. ${hint}`,
);
}
allVectors.push(vec);
}
}
return allVectors;
};
/**
* Embed a single query text via the HTTP backend.
* Convenience for MCP search where only one vector is needed.
*
* @param text - Query text to embed
* @returns Embedding vector as number arrayView on GitHub (pinned to d540b00184)
Solutions
- If GITNEXUS_EMBEDDING_DIMS is set: update it to match the returned width shown in the message (e.g. the endpoint returned 1536d → set GITNEXUS_EMBEDDING_DIMS=1536).
- If GITNEXUS_EMBEDDING_DIMS is unset: the message hint tells you exactly what to set, e.g. `Set GITNEXUS_EMBEDDING_DIMS=<returned> to match your model output`.
- If you requested truncation (GITNEXUS_EMBEDDING_REQUEST_DIMS=N), set GITNEXUS_EMBEDDING_DIMS=N too, since the returned width should equal the requested width.
- Re-index from scratch after changing dimensions — existing FLOAT[N] vectors are not auto-migrated.
Example fix
// before: using text-embedding-3-small (1536d) with default expected width # GITNEXUS_EMBEDDING_DIMS unset → expects 384 // after export GITNEXUS_EMBEDDING_DIMS=1536
Defensive patterns
Strategy: validation
Validate before calling
// After a model switch, confirm the declared width matches actual output:
const r = await fetch(`${URL}/embeddings`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${KEY}` }, body: JSON.stringify({ model: MODEL, input: 'probe' }) });
const j = await r.json();
const actual = j.data?.[0]?.embedding?.length;
const declared = parseInt(process.env.GITNEXUS_EMBEDDING_DIMS ?? '384', 10);
if (actual && actual !== declared) {
throw new Error(`Dimension mismatch: model returns ${actual}d but DIMS declares ${declared}`);
} Type guard
import { isHttpEmbeddingError } from 'gitnexus';
const isDimensionMismatch = (e: unknown): boolean =>
isHttpEmbeddingError(e) && e instanceof Error && e.message.startsWith('Embedding dimension mismatch'); Try / catch
try {
await httpEmbed(texts);
} catch (e) {
if (isDimensionMismatch(e)) {
// message hint says exactly what to set; update GITNEXUS_EMBEDDING_DIMS and re-index
}
throw e;
} Prevention
- Set GITNEXUS_EMBEDDING_DIMS to your model's native width, and to the truncated width if you use GITNEXUS_EMBEDDING_REQUEST_DIMS.
- After any model change, probe the actual output width and re-index.
- Keep indexer and MCP host on the same DIMS value to avoid query-time mismatch (error 139).
When it happens
Trigger: httpEmbed after httpEmbedBatch returns well-shaped items: new Float32Array(item.embedding).length !== (config.dimensions ?? 384). The endpoint's actual vector width disagrees with the declared/expected width. Common when GITNEXUS_EMBEDDING_DIMS is unset (default 384) but the model returns a different width, or when GITNEXUS_EMBEDDING_DIMS is set to a stale value after switching models.
Common situations: Switched from a 384d model to a 1536d model without updating GITNEXUS_EMBEDDING_DIMS. Left GITNEXUS_EMBEDDING_DIMS unset while using a non-384d model (default assumption is 384). Requested truncation via GITNEXUS_EMBEDDING_REQUEST_DIMS but forgot to set GITNEXUS_EMBEDDING_DIMS to the truncated width. Provider silently changed the model's output dimension.
Related errors
- Embedding dimension mismatch: endpoint returned ${embedding.
- ${source} must be true/false or a non-negative integer (node
- ${source} must be a boolean or a non-negative integer (node
- ${name} must be a positive integer, got "${value}"
- embedding device must be one of auto, dml, cuda, cpu, wasm;
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/44f112d66ff16e38.
Report an issue: GitHub.