FoundationAgents/MetaGPT · error · JSONDecodeError

Expecting value

Error message

Expecting value

What it means

Raised by MetaGPT's custom JSON decoder while parsing an object: after a key and colon, scan_once could not find any recognizable value (the internal iterator raised StopIteration, converted to JSONDecodeError 'Expecting value'). This decoder is a patched copy of the stdlib json scanner that additionally tolerates single quotes, triple quotes and other LLM-style JSON quirks. It still rejects a value position that is empty or starts with an invalid token.

Source

Thrown at metagpt/utils/custom_decoder.py:166

        # the JSON key separator is ": " or just ":".
        if s[end : end + 1] != ":":
            end = _w(s, end).end()
            if s[end : end + 1] != ":":
                raise JSONDecodeError("Expecting ':' delimiter", s, end)
        end += 1

        try:
            if s[end] in _ws:
                end += 1
                if s[end] in _ws:
                    end = _w(s, end + 1).end()
        except IndexError:
            pass

        try:
            value, end = scan_once(s, end)
        except StopIteration as err:
            raise JSONDecodeError("Expecting value", s, err.value) from None
        pairs_append((key, value))
        try:
            nextchar = s[end]
            if nextchar in _ws:
                end = _w(s, end + 1).end()
                nextchar = s[end]
        except IndexError:
            nextchar = ""
        end += 1

        if nextchar == "}":
            break
        elif nextchar != ",":
            raise JSONDecodeError("Expecting ',' delimiter", s, end - 1)
        end = _w(s, end).end()
        nextchar = s[end : end + 1]
        end += 1
        if nextchar != '"':

View on GitHub (pinned to 11cdf466d0)

Solutions

  1. Inspect the reported position in the input string to see the exact token that failed, and fix the malformed value.
  2. Pre-sanitize LLM output: replace Python literals with JSON ones (None->null, True->true, False->false) before decoding.
  3. If the text may be truncated, wrap with a repair/partial-JSON routine or feed the output through metagpt's own code extraction (e.g. extract JSON blocks) instead of decoding the whole message.
  4. Catch json.JSONDecodeError and retry the LLM call asking for strictly valid JSON.

Example fix

// before
import json
obj = json.loads(llm_output)  # ValueError: Expecting value on '{"a": }'

// after
from metagpt.utils.common import output_parser
obj = output_parser.parse_json_with_markdown_code(llm_output)  # extracts+repairs the JSON block first
Defensive patterns

Strategy: try-catch

Validate before calling

import json
text = llm_output.strip()
try:
    json.loads(text)
except json.JSONDecodeError as e:
    print('not valid JSON yet:', e.msg, 'at pos', e.pos)

Type guard

def is_parseable_json(text: str) -> bool:
    try:
        json.loads(text)
        return True
    except (json.JSONDecodeError, ValueError):
        return False

Try / catch

from json import JSONDecodeError
try:
    obj = decoder.decode(s)
except JSONDecodeError as e:
    # e.msg, e.pos locate the failure; log context around pos
    logger.warning('JSON decode failed: %s at %d', e.msg, e.pos)
    obj = repair_and_retry(s)  # sanitize None/True/False or re-ask the LLM

Prevention

When it happens

Trigger: Calling the decoder (e.g. metagpt.utils.custom_decoder.JSONDecoder / repair_partial_json on LLM output) on text like {"a": } (missing value), {"a": ,"b":1}, or a value beginning with a character that is not a valid JSON value start (e.g. {"a": NaN-style tokens the scanner does not accept, or unquoted barewords other than true/false/null).

Common situations: Parsing raw LLM responses where the model omitted a value, emitted Python literals (None, NaN) instead of JSON (null, NaN is invalid in strict JSON), or truncated output cut a value off. Also occurs when repair-style decoding is applied to text that only looks partially like JSON.

Related errors


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