Context
Diagnosing a live external deployment on 2026-08-07, the only thing readable about its embed failure was:
lastErrorCode = KB_TENANT_REPO_SYNC_SYNC_FAILED
lastSourceErrorCode = KB_VECTOR_EMBED_FAILED
lastIngestedRev = null
That is the whole receipt, and it names a stage. Hours went into deciding whether it was the same defect as #16566, which had been diagnosed on a different plane — a question the receipt could not answer either way, because the code it carries is the same regardless of cause.
The Problem
ai/services/knowledge-base/IngestionService.mjs:388 and :406:
code: result.code || 'KB_VECTOR_EMBED_FAILED',
KB_VECTOR_EMBED_FAILED is a fallback. It fires precisely when the underlying error carried no code of its own — so the receipt is at its least informative exactly when the failure is least understood. A provider error that does carry a code surfaces it; the unrecognised ones, which are the interesting ones, all collapse to one string.
The message and details are attached at the throw site. They do not reach the surface a remote diagnostician reads: snapshot.tenantRepoSync.repos[] carries lastSourceErrorCode and no message field. So the detail exists in the process and is absent from the artifact.
Why that is expensive rather than untidy. The code spans providers that share no implementation. TextEmbeddingService branches at :1043 / :1059:
| deployment |
NEO_EMBEDDING_PROVIDER |
transport |
branch |
| external |
ollama |
in-compose container |
#embedOllama |
| this plane |
openAiCompatible |
host process |
the openAiCompatible request queue |
Two deployments reporting KB_VECTOR_EMBED_FAILED may share nothing but the stage at which they stopped. Treating the match as a shared defect is the natural reading and it is unsupported — I made exactly that inference and stated it in a deployment guide before checking the branch.
The Architectural Reality
ai/services/knowledge-base/IngestionService.mjs:388,406 — the fallback, with message and details populated but not carried.
ai/services/memory-core/TextEmbeddingService.mjs:1043,1059 — the provider split the single code sits above.
snapshot.tenantRepoSync.repos[] — the remote-readable surface; lastSourceErrorCode only.
#16568 is the neighbouring gap on the revision axis: a deployment could not report which commit it runs. Same family — a fact the process holds and the artifact drops.
The Fix
Direction, not prescription.
Carry a bounded cause alongside the code. The receipt already has message and details at the throw site; the surface needs a redacted, length-capped lastSourceErrorMessage (or a provider-plus-reason pair) so a reader can tell two different faults apart without shell access to the box.
And make the fallback rarer. A provider error reaching this point without a code is itself the defect — the ollama and openAiCompatible branches should classify their own failures, so KB_VECTOR_EMBED_FAILED means "unclassified" rather than "embedding, cause unrecorded".
Redaction is a live constraint, not an afterthought: provider errors can echo request content. Whatever surfaces must be bounded and scrubbed by construction rather than by hoping the message is short.
Acceptance Criteria
Out of Scope
#16566 — the embed-stage failure on this plane. This ticket is why that one is hard to compare against any other deployment, not the failure itself.
- Fixing any particular provider's error classification. Naming the gap is enough here; the branches can be done as they are touched.
- The tenant-sync error taxonomy above the ingest layer.
Avoided Traps
- Reading a shared error code as a shared fault. It is the intuitive inference and the code's construction makes it wrong: a fallback string says the most when the cause is known and the least when it is not.
- Assuming the detail is lost because it was never captured. It is captured —
message and details are both populated at the throw. Only the surface drops them, which makes this a plumbing fix rather than an instrumentation project.
- Surfacing the raw message. Provider errors can quote the input. The fix is a bounded, redacted field, not a passthrough.
Related
#16566 (the embed-stage failure this made hard to compare) · #16568 (the revision a deployment could not report — same family, different axis) · #16577.
Live latest-open sweep: checked the latest 20 open issues at 2026-08-07T18:09:08Z; no equivalent found. A2A in-flight claim sweep: no competing claim on this scope.
Origin Session ID: 9ced67a1-8f21-4da2-a1bf-a2a968c47ed2
Retrieval Hint: query_raw_memories("KB_VECTOR_EMBED_FAILED fallback code names the stage not the cause, ollama vs openAiCompatible branch, receipt drops message")
Retrieval Hint: the discriminating read is code: result.code || 'KB_VECTOR_EMBED_FAILED' — a fallback is least informative exactly when the failure is least understood.
Context
Diagnosing a live external deployment on 2026-08-07, the only thing readable about its embed failure was:
That is the whole receipt, and it names a stage. Hours went into deciding whether it was the same defect as
#16566, which had been diagnosed on a different plane — a question the receipt could not answer either way, because the code it carries is the same regardless of cause.The Problem
ai/services/knowledge-base/IngestionService.mjs:388and:406:code: result.code || 'KB_VECTOR_EMBED_FAILED',KB_VECTOR_EMBED_FAILEDis a fallback. It fires precisely when the underlying error carried no code of its own — so the receipt is at its least informative exactly when the failure is least understood. A provider error that does carry a code surfaces it; the unrecognised ones, which are the interesting ones, all collapse to one string.The
messageanddetailsare attached at the throw site. They do not reach the surface a remote diagnostician reads:snapshot.tenantRepoSync.repos[]carrieslastSourceErrorCodeand no message field. So the detail exists in the process and is absent from the artifact.Why that is expensive rather than untidy. The code spans providers that share no implementation.
TextEmbeddingServicebranches at:1043/:1059:NEO_EMBEDDING_PROVIDERollama#embedOllamaopenAiCompatibleTwo deployments reporting
KB_VECTOR_EMBED_FAILEDmay share nothing but the stage at which they stopped. Treating the match as a shared defect is the natural reading and it is unsupported — I made exactly that inference and stated it in a deployment guide before checking the branch.The Architectural Reality
ai/services/knowledge-base/IngestionService.mjs:388,406— the fallback, withmessageanddetailspopulated but not carried.ai/services/memory-core/TextEmbeddingService.mjs:1043,1059— the provider split the single code sits above.snapshot.tenantRepoSync.repos[]— the remote-readable surface;lastSourceErrorCodeonly.#16568is the neighbouring gap on the revision axis: a deployment could not report which commit it runs. Same family — a fact the process holds and the artifact drops.The Fix
Direction, not prescription.
Carry a bounded cause alongside the code. The receipt already has
messageanddetailsat the throw site; the surface needs a redacted, length-cappedlastSourceErrorMessage(or a provider-plus-reason pair) so a reader can tell two different faults apart without shell access to the box.And make the fallback rarer. A provider error reaching this point without a code is itself the defect — the ollama and openAiCompatible branches should classify their own failures, so
KB_VECTOR_EMBED_FAILEDmeans "unclassified" rather than "embedding, cause unrecorded".Redaction is a live constraint, not an afterthought: provider errors can echo request content. Whatever surfaces must be bounded and scrubbed by construction rather than by hoping the message is short.
Acceptance Criteria
KB_VECTOR_EMBED_FAILED's meaning is documented at the throw site as unclassified, so a future reader does not repeat the "same code, same defect" inference.Out of Scope
#16566— the embed-stage failure on this plane. This ticket is why that one is hard to compare against any other deployment, not the failure itself.Avoided Traps
messageanddetailsare both populated at the throw. Only the surface drops them, which makes this a plumbing fix rather than an instrumentation project.Related
#16566(the embed-stage failure this made hard to compare) ·#16568(the revision a deployment could not report — same family, different axis) ·#16577.Live latest-open sweep: checked the latest 20 open issues at 2026-08-07T18:09:08Z; no equivalent found. A2A in-flight claim sweep: no competing claim on this scope.
Origin Session ID: 9ced67a1-8f21-4da2-a1bf-a2a968c47ed2
Retrieval Hint:
query_raw_memories("KB_VECTOR_EMBED_FAILED fallback code names the stage not the cause, ollama vs openAiCompatible branch, receipt drops message")Retrieval Hint: the discriminating read is
code: result.code || 'KB_VECTOR_EMBED_FAILED'— a fallback is least informative exactly when the failure is least understood.