Skip to content

run_state.json / report meta.json emit malformed JSON (unescaped control characters) #57

Description

@Quantum-eon

Summary

The backend writes run_state.json and the report's meta.json with raw, unescaped control characters embedded in LLM-generated text fields (agent action strings, report markdown). The resulting files fail standard parsing (json.load raises), which breaks any downstream tooling that consumes run artifacts. We had to fall back to regex extraction to build our run manifests.

Reproduction

  1. Complete (or partially complete) any simulation run whose agents emit multi-line or control-character-containing text — in practice, nearly every run.
  2. python -c "import json; json.load(open('run_state.json'))"json.decoder.JSONDecodeError (invalid control character).
  3. Same for the generated report's meta.json.

Observed

  • Unescaped control characters (raw newlines/tabs and similar) inside JSON string values in action and markdown-carrying fields.
  • Standard-library and strict parsers reject the files; only lenient/regex extraction works. This affected effectively all of our 18 runs' manifest tooling.

Expected

All emitted .json artifacts should be valid JSON parseable by json.load with default (strict) settings.

Suggested fix

Serialize these artifacts with proper JSON encoding rather than string templating/concatenation — i.e. build a dict and json.dump(obj, f, ensure_ascii=False) so the encoder escapes control characters. If any field is currently interpolated into a JSON template as a raw string, route it through json.dumps instead. A round-trip test (json.load on every emitted artifact) in CI would prevent regressions.

Context / disclosure: We are an independent research team auditing multi-agent simulation pipelines. We found this while running a systematic 18-run study on MiroFish-Offline across four LLM families. We plan to publish a reproducible study referencing this issue in roughly 4 weeks, and we're happy to share drafts with maintainers beforehand. Thank you for open-sourcing this project — it made this kind of research possible in the first place.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions