#17974·theia

ai-chat-ui: extractJsonStringField parses the full string before its regex fallback

Author: safisaCreated Aug 31, 2026Updated Sep 14, 2026
Labelsbugtheia-ai

Bug Description:

extractJsonStringField in packages/ai-chat-ui/src/common/toolcall-utils.ts tries JSON.parse on the whole string first and only falls back to a regex when it throws:

typescript
try {
    const parsed = JSON.parse(json);
    ...
} catch {
    const regex = new RegExp('"' + fieldName + '"\\s*:\\s*"([^"]*)"?');
    return regex.exec(json)?.[1];
}

The fallback exists for streaming, where the arguments are truncated and therefore invalid JSON — so during streaming the parse always throws, and JSON.parse still scans the entire string before failing. It is called from getArgumentsLabel in the body of ToolCallContent (toolcall-part-renderer.tsx), i.e. on every render while the arguments grow, making the label quadratic in argument size.

Measured with 64-char deltas: 1 MB of arguments → ~7 s of CPU, 2 MB → ~27 s. Conflated tree updates bring this down in practice, but it is pure waste — the regex alone answers in microseconds.

Suggested fix: try the regex first and fall back to JSON.parse (or skip the parse when the string is not yet balanced).

Separately, the regex matches the first "<field>": "..." anywhere in the string, including inside a content value — writing a JSON file that itself has a "path" property shows the wrong label. Cosmetic, but wrong.

Steps to Reproduce:

  1. In agent mode, have the agent call writeFileContent with a multi-megabyte content argument (e.g. an embedded base64 image).
  2. Profile the frontend while the arguments stream in — JSON.parse under extractJsonStringField dominates.

Additional Information

  • Operating System: macOS 26.6.2
  • Theia Version: 1.75.0