Skip to content

fix: use strict=False for JSON parsing of tool calls and session data#1460

Closed
Br1an67 wants to merge 1 commit intoMoonshotAI:mainfrom
Br1an67:fix/json-control-chars
Closed

fix: use strict=False for JSON parsing of tool calls and session data#1460
Br1an67 wants to merge 1 commit intoMoonshotAI:mainfrom
Br1an67:fix/json-control-chars

Conversation

@Br1an67
Copy link
Copy Markdown

@Br1an67 Br1an67 commented Mar 17, 2026

Problem

LLM responses sometimes contain raw control characters (newlines, tabs) inside JSON string values in tool call arguments. With the default strict=True, json.loads() rejects these, causing:

  1. Tool call execution failures
  2. Corrupted context.jsonl lines that prevent session restoration

Fix

Use json.loads(..., strict=False) in all critical JSON parsing paths:

  • soul/toolset.py — tool call argument parsing
  • soul/context.py — session restore and checkpoint revert
  • tools/__init__.py — tool argument extraction for display
  • ui/shell/debug.py — debug tool call formatting

Testing

Verified that json.loads('{"key": "value\nwith newline"}', strict=False) correctly parses control characters that would fail with strict=True.

Fixes #1378


Open with Devin

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 2 additional findings.

Open in Devin Review

When an LLM generates tool_call.function.arguments containing literal
control characters (e.g. unescaped newlines in multi-line strings),
json.loads() raises JSONDecodeError because Python's JSON parser
rejects unescaped control characters (U+0000–U+001F) by default.

This causes tool execution to fail, and the malformed arguments are
persisted to the session context file, making the session
irrecoverable on restore.

Fix: use json.loads(strict=False) at all relevant call sites:
- toolset.py: tool argument parsing
- context.py: session restore and checkpoint revert
- visualize.py: URL extraction from tool arguments

Closes MoonshotAI#1378
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JSON parsing error when tool call arguments contain control characters

2 participants