Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[Engine] An array or object tool parameter with a raw newline inside a string reaches the client as a string

Open Beginner friendly
#4,630 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 3 days

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
78/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
python

Research direction

Read the two parsing paths named in the report: parse_tool_call at serve/frontend.py:931-935 and the streaming parser's raw state at serve/frontend.py:1274-1277. Reproduce with a non-string parameter containing a raw newline inside a JSON string, then check both paths handle it consistently. Done when the value reaches the client as an array or object and malformed JSON still uses the existing fallback.

Written by the indexing model from the issue text.

Description

Area

[Engine] (speed, kernels, models, the server and API)

Desktop app, Terminal or source?

Desktop app (Windows, Linux or Mac)

What happened

A tool call whose array or object parameter holds multi-line text reaches the client as a string instead of the array or object, and the client rejects the call.

In the Qwen XML form (<parameter=edits>…</parameter>) the model writes the value as raw text. For a parameter whose declared type is not string, the parser runs json.loads(value) and, when that raises, silently passes the raw text through as a string:

  • parse_tool_call, serve/frontend.py:931-935 on main 46c152a1
  • the streaming parser's raw state, serve/frontend.py:1274-1277

The model typically writes a line break inside a JSON string as a real newline, not as \n. That is natural in this format and is what an agent editing a Markdown file or source code does. Python's default json.loads (strict=True) refuses a raw control character inside a string, so the whole value falls back to a string:

Invalid control character at: line 1 column 74 (char 73)

The value itself was a correct array of {"old_str", "new_str"} objects. json.loads(value, strict=False) parses it into exactly that array.

Seen with Forge (VS Code agent) as the client, on an edit_file call whose edits parameter is declared as an array. The client answered edits arrived as a string, not an array and is not valid JSON. The model recovered by switching to a flat single-edit form, but it costs a round each time, and it happens often on long agent sessions that edit Markdown.

Expected: a raw newline or tab inside a string in a non-string parameter parses as part of that string.

Suggested fix: json.loads(value, strict=False) at both sites. Valid JSON parses exactly as before. The only change is that raw control characters inside strings are accepted, which is what the XML parameter format produces. A parameter that is still not JSON keeps today's fallback.

Smallest steps or command that reproduce it
import json
s = '[{"old_str": "a", "new_str": "line one\nline two"}]'   # a real newline inside new_str
json.loads(s)                 # ValueError: Invalid control character at: line 1 column 39 (char 38)
json.loads(s, strict=False)   # [{'old_str': 'a', 'new_str': 'line one\nline two'}]

Feeding parse_tool_call a <tool_call><function=edit_file><parameter=edits> block with that value and a schema declaring edits as array returns arguments["edits"] as str.

Reproduction status

Reproduced locally

Strata version

engine 0.1.52 (the code paths above checked on main 46c152a1)

Graphics card, memory and system

2x RTX 5060 Ti 16 GB + RTX 3060 12 GB, Windows 10 Pro

Model, size and settings

Qwen3.8-Flash-Next IQ2_XS, 400K context. The model is not the cause: the parameter value it wrote was correct JSON apart from the raw newlines.

Dominant language
C++
Stars
11.6k
Forks
1k
PR merge metrics
No merged PRs in 30d

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from Niko1221/Strata

All issues in Niko1221/Strata

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.