FoundationAgents/MetaGPT · error · JSONDecodeError

Unterminated string starting at

Error message

Unterminated string starting at

What it means

Raised inside py_scanstring of MetaGPT's custom decoder: the STRINGCHUNK regex (selected by the delimiter: ", ', triple-double or triple-single quote) stopped matching before a closing delimiter was found, so the string never terminates within the remaining input.

Solutions

  1. Add the missing closing delimiter at the position indicated by 'starting at' in the message.
  2. If output was truncated by max_tokens, increase the limit or ask for shorter output and regenerate.
  3. For partial/repaired JSON, append synthetic closing quotes/braces before decoding (this is what repair_partial_json-style helpers do).
  4. Escape inner quotes (\") so the intended terminator is the real end of the string.

Example fix

// before
s = '{"desc": "unfinished'   # Unterminated string starting at
obj = decoder.decode(s)

// after
s = '{"desc": "unfinished"}'
obj = decoder.decode(s)
Defensive patterns

Strategy: try-catch

Validate before calling

def has_balanced_quotes(s: str, delim: str = '"') -> bool:
    # crude check: count unescaped delimiters outside the payload
    import re
    body = s.strip()
    hits = re.findall(r'(?<!\\)' + re.escape(delim), body)
    return len(hits) % 2 == 0

Try / catch

try:
    obj = decoder.decode(s)
except json.JSONDecodeError as e:
    if e.msg.startswith('Unterminated string'):
        s += '"}'  # close dangling string+object for partial output
        obj = decoder.decode(s)

Prevention

When it happens

Trigger: Decoding text with an unclosed string, e.g. {"a": "hello} , a string ending at end-of-input without its closing quote, or triple-quoted content ('"""...') whose closing triple quote is missing. The delimiter choice (e.g. '"""') that does not appear later in the text also triggers it.

Common situations: Truncated LLM output cut off mid-string (very common with max_tokens limits), unescaped inner quote that ends the chunk early, or expecting triple-quote support when the content only has single/double quotes.

Related errors


AI-assisted analysis of FoundationAgents/MetaGPT@11cdf466d0 (2026-08-14). Data as JSON: /api/errors/9439d1653574b245. Report an issue: GitHub.

Appendix: source

Thrown at metagpt/utils/custom_decoder.py:227

        tuple: A tuple containing the decoded string and the index of the character in `s`
        after the end quote.
    """

    chunks = []
    _append = chunks.append
    begin = end - 1
    if delimiter == '"':
        _m = STRINGCHUNK.match
    elif delimiter == "'":
        _m = STRINGCHUNK_SINGLEQUOTE.match
    elif delimiter == '"""':
        _m = STRINGCHUNK_TRIPLE_DOUBLE_QUOTE.match
    else:
        _m = STRINGCHUNK_TRIPLE_SINGLEQUOTE.match
    while 1:
        chunk = _m(s, end)
        if chunk is None:
            raise JSONDecodeError("Unterminated string starting at", s, begin)
        end = chunk.end()
        content, terminator = chunk.groups()
        # Content is contains zero or more unescaped string characters
        if content:
            _append(content)
        # Terminator is the end of string, a literal control character,
        # or a backslash denoting that an escape sequence follows
        if terminator == delimiter:
            break
        elif terminator != "\\":
            if strict:
                # msg = "Invalid control character %r at" % (terminator,)
                msg = "Invalid control character {0!r} at".format(terminator)
                raise JSONDecodeError(msg, s, end)
            else:
                _append(terminator)
                continue
        try:

View on GitHub (pinned to 11cdf466d0)