JuliusBrussee/caveman · error

encode report: %w

Error message

encode report: %w

What it means

json.Marshal of the compressReport (engine Result plus error code) failed. The report struct contains engine counters and an error-code string, so marshal failures are essentially impossible for well-formed engine Results — this error signals memory exhaustion or a corrupted Result (e.g. NaN/Inf in a numeric field).

Source

Thrown at engine/cmd/caveman-engine/main.go:138

// the original bytes. Any contradictory result fails rather than guessing.
func emitCompressResult(input []byte, res engine.Result, compressErr error, stdout, stderr io.Writer) error {
	code := ""
	if compressErr != nil {
		if !bytes.Equal(res.Output, input) || !res.PassedThrough() || res.TokensAfter != res.TokensBefore {
			return fmt.Errorf("unsafe recovery failure result: %w", compressErr)
		}
		code = "cave_ccr_unavailable"
		if errors.Is(compressErr, ccr.ErrBudgetExceeded) {
			code = "cave_ccr_budget_exceeded"
		}
	}
	if _, err := stdout.Write(res.Output); err != nil {
		return fmt.Errorf("write stdout: %w", err)
	}
	// Report stays on stderr so stdout remains clean payload bytes.
	report, err := json.Marshal(compressReport{Result: res, Error: code})
	if err != nil {
		return fmt.Errorf("encode report: %w", err)
	}
	if _, err := fmt.Fprintln(stderr, string(report)); err != nil {
		return fmt.Errorf("write report: %w", err)
	}
	return nil
}

func runDetect() {
	input, err := readBoundedInput(os.Stdin, maxStdinBytes)
	if err != nil {
		fatal("read stdin: %v", err)
	}
	// Detection needs no store.
	eng := engine.New(nil, nil)
	fmt.Println(eng.Detect(input))
}

func runRetrieve(args []string) {

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. If you forked the engine, ensure numeric Result fields never hold NaN/Inf (validate before returning).
  2. Check the process memory limit and raise it if the OOM killer or allocator is involved.
  3. Reproduce with the stock binary to rule out local modifications.
  4. If it persists on stock builds, report it — stdout already received the payload, only the stderr report was lost.
Defensive patterns

Strategy: try-catch

Prevention

When it happens

Trigger: emitCompressResult building the JSON report when a numeric field in res holds a value JSON cannot encode (NaN, +Inf) — normally prevented by engine validation — or an out-of-memory condition during marshal.

Common situations: A patched/forked engine Result introducing an unencodable field; running under a hard memory limit (cgroup) so marshal allocation fails.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/685b57a9df198e21. Report an issue: GitHub.