Root cause (proven)
der reindex on a v14-era store fails per-konfig with ---: malformed value.
- The konfig blob (
!toml-config-v2) is stored hyphence-framed: ---\n! toml-config-v2\n---\n\n<body>. The blob is intact (verified via madder cat).
- tommy ≥ v0.4.3 (pinned:
v0.4.4-0.20260608202535-1ae69d31ec4f) made the TOML parser strict about a leading --- fence. decomposeValue (tommy/pkg/cst/decompose.go:280) returns fmt.Errorf("%s: malformed value", path) with path == "---".
- The reindex iterator
AllInventoryListObjectsAndContents (internal/india/inventory_list_store/main.go:346) decodes contained konfig records via the config-decode path (internal/charlie/repo_configs/v2_tommy.go:35 DecodeV2 → document.Parse → cst.Decompose) without stripping the hyphence frame, so tommy sees the --- line and errors.
- Reproduced in isolation:
DecodeV2([]byte(wrapped)) returns exactly ---: malformed value.
Known-adjacent
internal/charlie/repo_configs/lenient_parse_test.go is t1.Skip-ped with a comment asserting "Production never does this: hyphence's CoderToTypedBlob.DecodeFrom strips the ---/type-line frame (readMetadataFrom) before the body reaches the bare blob decoder." The reindex path disproves that assumption — it is a production path that feeds framed bytes to the bare decoder.
Fix
Ensure the inventory-list-contents config decode strips the hyphence frame before cst.Decompose (align with CoderToTypedBlob.DecodeFrom / readMetadataFrom), so tommy only ever sees the TOML body. Then un-skip lenient_parse_test.go (or replace it with a test asserting the framed konfig decodes via the production iterator path) as the regression guard.
Notes
- Only
!toml-config-v2 records are affected (only they route through tommy with a --- wrapper); !md/!toml-type-v2 in the same list decode fine.
madder cat of the list blob succeeds because it never runs tommy decompose on the contained config blob.
Verify
BATS (deterministic): a v14 fixture store containing a framed konfig, run reindex, assert zero objects with errors and no malformed value.
:clown: filed by Clown (0.4.0+cd38c2d) — built from cd38c2d
Root cause (proven)
der reindexon a v14-era store fails per-konfig with---: malformed value.!toml-config-v2) is stored hyphence-framed:---\n! toml-config-v2\n---\n\n<body>. The blob is intact (verified viamadder cat).v0.4.4-0.20260608202535-1ae69d31ec4f) made the TOML parser strict about a leading---fence.decomposeValue(tommy/pkg/cst/decompose.go:280) returnsfmt.Errorf("%s: malformed value", path)withpath == "---".AllInventoryListObjectsAndContents(internal/india/inventory_list_store/main.go:346) decodes contained konfig records via the config-decode path (internal/charlie/repo_configs/v2_tommy.go:35DecodeV2→document.Parse→cst.Decompose) without stripping the hyphence frame, so tommy sees the---line and errors.DecodeV2([]byte(wrapped))returns exactly---: malformed value.Known-adjacent
internal/charlie/repo_configs/lenient_parse_test.goist1.Skip-ped with a comment asserting "Production never does this: hyphence'sCoderToTypedBlob.DecodeFromstrips the---/type-line frame (readMetadataFrom) before the body reaches the bare blob decoder." The reindex path disproves that assumption — it is a production path that feeds framed bytes to the bare decoder.Fix
Ensure the inventory-list-contents config decode strips the hyphence frame before
cst.Decompose(align withCoderToTypedBlob.DecodeFrom/readMetadataFrom), so tommy only ever sees the TOML body. Then un-skiplenient_parse_test.go(or replace it with a test asserting the framed konfig decodes via the production iterator path) as the regression guard.Notes
!toml-config-v2records are affected (only they route through tommy with a---wrapper);!md/!toml-type-v2in the same list decode fine.madder catof the list blob succeeds because it never runs tommy decompose on the contained config blob.Verify
BATS (deterministic): a v14 fixture store containing a framed konfig, run
reindex, assert zeroobjects with errorsand nomalformed value.:clown: filed by Clown (0.4.0+cd38c2d) — built from cd38c2d