Yesterday, memory ingestion stopped working. Not slow. Not degraded. Completely broken—zero percent recall.
The issue surfaced when biographical data started failing to ingest into Sabine's memory layer. What looked like a single problem turned out to be three separate bugs that had compounded into total system failure.
What Broke
Bug one: The input_type constructor in our langchain-voyageai integration was malformed. Version 0.1.3 of the library doesn't accept the parameter we were passing, which meant embeddings couldn't be generated for incoming memory data.
Bug two: Entity UUIDs were being constructed incorrectly. When the system tried to link biographical facts to entities, it generated malformed identifiers that couldn't be stored or retrieved.
Bug three: The FamilyMember parser was failing silently on valid input. Family relationship data—one of the most important biographical signals—was being dropped before it ever reached the memory layer.
How We Found It
The initial symptom was simple: memories weren't being ingested. But the root causes were scattered across three different modules—biographical.py, memory.py, and our regression test suite.
We traced the failure backward through the ingestion pipeline. First, we confirmed that the embedding generation was failing due to the incorrect constructor call. That was RC-3, a recent change that looked reasonable in isolation but broke compatibility with the underlying library.
Next, we isolated the UUID generation logic and found that entities were being created with invalid identifiers. Even if embeddings had worked, those memories would never have been retrievable.
Finally, the FamilyMember parser revealed itself during manual testing. The parser was silently swallowing errors, so the logs showed success while data was being lost.
The Fix
We reverted the broken input_type constructor, corrected the entity UUID generation logic, and fixed the FamilyMember parser to properly handle and report errors. All three changes shipped together in commit 535dec5.
We also added a new regression test (test_v4_retrieval_regression.py) to ensure that this specific failure pattern—embedding generation, entity creation, and biographical parsing working in concert—gets validated on every commit going forward.
What's Next
Memory ingestion is operational again, but this incident exposed a broader issue: our integration tests weren't catching cross-module failures. A change in the embedding layer shouldn't be able to silently break the entire memory pipeline.
We're expanding test coverage to include end-to-end memory ingestion scenarios that validate the entire chain—from biographical input through embedding generation, entity creation, storage, and retrieval. The goal is to make sure that if any component breaks, the test suite fails immediately and visibly.
We're also reviewing our error handling strategy. Silent failures are dangerous. If a parser can't process input, it should fail loudly, not drop data and continue.
Strug Works is built to ship fast, but fast only works if the foundation is reliable. This fix restores that reliability, and the new tests ensure it stays that way.