langchain-ai/deepagents · error · ValueError

Unclosed {quote} in --model-params value

Error message

Unclosed {quote} in --model-params value

What it means

When the --model-params value starts with a quote, _extract_model_params_flag scans forward for the matching unescaped closing quote (backslash-escaped quotes are skipped). If the scan reaches the end of the argument without finding it, it raises ValueError indicating the quote character was never closed. shlex is then used to unescape the quoted token.

Source

Thrown at libs/code/deepagents_code/app.py:1951

        msg = "--model-params requires a JSON object value"
        raise ValueError(msg)

    # Determine the JSON string boundaries.
    if after[0] in {"'", '"'}:
        quote = after[0]
        end = -1
        backslash_count = 0
        for i, ch in enumerate(after[1:], start=1):
            if ch == "\\":
                backslash_count += 1
                continue
            if ch == quote and backslash_count % 2 == 0:
                end = i
                break
            backslash_count = 0
        if end == -1:
            msg = f"Unclosed {quote} in --model-params value"
            raise ValueError(msg)
        # Parse the quoted token with shlex so escaped quotes are unescaped.
        json_str = shlex.split(after[: end + 1], posix=True)[0]
        rest = after[end + 1 :].lstrip()
    elif after[0] == "{":
        # Walk forward to find the matching closing brace.
        depth = 0
        end = -1
        for i, ch in enumerate(after):
            if ch == "{":
                depth += 1
            elif ch == "}":
                depth -= 1
                if depth == 0:
                    end = i
                    break
        if end == -1:
            msg = "Unbalanced braces in --model-params value"
            raise ValueError(msg)

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Add the matching closing quote to the value: --model-params '{"temperature":0.2}'.
  2. Wrap the JSON in single quotes so inner double quotes survive the shell, and avoid stray backslashes before the final quote.
  3. Print the raw argv (or the command after shell expansion) to confirm the value retains both quotes.

Example fix

# before (closing quote eaten by nested shell quoting)
dcode --model-params "{'temperature':0.2}

# after
dcode --model-params '{"temperature":0.2}'
Defensive patterns

Strategy: try-catch

Validate before calling

value = raw.split(None, 1)[1].strip() if len(raw.split(None, 1)) > 1 else ''
if value[:1] in {'\'', '"'} and value[-1:] != value[0]:
    raise SystemExit(f"unclosed quote in --model-params value")

Try / catch

try:
    handle_command(argv)
except ValueError as e:
    if "Unclosed" in str(e):
        print("quote the JSON with matching single quotes: --model-params '{...}'")
        sys.exit(2)
    raise

Prevention

When it happens

Trigger: Passing --model-params '"temperature":0.2' or '{"temperature":0.2} (opening quote present, closing quote missing) on the command line.

Common situations: Shell quoting pitfalls: the closing quote was consumed by the outer shell (e.g. nested quotes in a script); truncation when pasting multi-line JSON; escaping confusion where a backslash before the final quote makes it look escaped to the parser.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/e7431b9e6522d277. Report an issue: GitHub.