JuliusBrussee/caveman · info
not valid TOON
Error message
not valid TOON
What it means
toonDecodeBytes was given bytes that DecodeTOON cannot parse as TOON. Decoding fails closed with an error — it never emits partial or guessed JSON — so malformed or truncated TOON input is surfaced rather than silently corrupted.
Source
Thrown at engine/cmd/caveman-engine/main.go:623
// toonEncodeBytes converts JSON to the lossless TOON subset. It fails closed:
// any input that is not valid JSON, or whose shape is outside the proven
// round-trip subset (deeply nested / non-uniform), returns an error rather than a
// lossy approximation — so the caller keeps JSON instead of trusting bad TOON.
func toonEncodeBytes(input []byte) ([]byte, error) {
out, ok := compressors.NewTOON().Compress(input)
if !ok {
return nil, fmt.Errorf("not losslessly TOON-encodable (invalid JSON, or nested/non-uniform shape); keep JSON")
}
return out, nil
}
// toonDecodeBytes converts TOON back to compact JSON. Malformed TOON fails closed
// with an error; it never emits partial or guessed JSON.
func toonDecodeBytes(input []byte) ([]byte, error) {
v, ok := compressors.DecodeTOON(input)
if !ok {
return nil, fmt.Errorf("not valid TOON")
}
out, err := json.Marshal(v)
if err != nil {
return nil, err
}
return out, nil
}
func runEvals(args []string) {
if len(args) < 1 || args[0] != "run" {
fatal("usage: caveman-engine evals run [--fixtures DIR]")
}
fixtureDir := ""
if len(args) == 3 && args[1] == "--fixtures" && args[2] != "" {
fixtureDir = args[2]
} else if len(args) != 1 {
fatal("usage: caveman-engine evals run [--fixtures DIR]")
}View on GitHub (pinned to 27d5a3981a)
Solutions
- Verify the producer actually emitted TOON — remember encode intentionally falls back to JSON on unsupported shapes, so detect format first.
- Check the payload for truncation (compare lengths/hashes end to end).
- Keep producer and consumer on the same engine/compressors version.
- On error, surface it upstream rather than retrying blindly — the bytes are wrong, not the timing.
Example fix
// before
json_out, err := toonDecodeBytes(payload)
// after: sniff format, decode conditionally
var json_out []byte
if compressors.IsTOON(payload) { json_out, err = toonDecodeBytes(payload) } else { json_out = payload } Defensive patterns
Strategy: type-guard
Type guard
func isTOON(b []byte) bool {
_, ok := compressors.DecodeTOON(b)
return ok
} Try / catch
if out, err := toonDecodeBytes(payload); err != nil {
// payload is not TOON: either plain JSON or corrupt; handle explicitly
return handleNonTOON(payload)
} else {
use(out)
} Prevention
- Carry a format marker (sidecar flag or magic) alongside the payload.
- Remember encode may fall back to JSON, so always sniff before decoding.
- Verify payload integrity (length/hash) across transports.
When it happens
Trigger: Calling toonDecodeBytes on data that is not TOON-encoded (e.g. still plain JSON because encoding fell back, or hand-mangled/truncated TOON).
Common situations: Round-trip asymmetry where encode fell back to JSON but the consumer assumes TOON; truncated payload from a transport; version skew between TOON writer and reader.
Related errors
- not losslessly TOON-encodable (invalid JSON, or nested/non-u
- cave_budget_denomination_unavailable
- cave_claude_reasoning_capability_unknown:${model}
- cave_sandbox_conformance_failed
- cave_memory_provenance_unsupported: only "local" memory is s
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/40134ebf075effe9.
Report an issue: GitHub.