{"record":{"id":"e7431b9e6522d277","repo":"langchain-ai/deepagents","slug":"unclosed-quote-in-model-params-value","errorCode":null,"errorMessage":"Unclosed {quote} in --model-params value","messagePattern":"Unclosed (.+?) in --model-params value","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/app.py","lineNumber":1951,"sourceCode":"        msg = \"--model-params requires a JSON object value\"\n        raise ValueError(msg)\n\n    # Determine the JSON string boundaries.\n    if after[0] in {\"'\", '\"'}:\n        quote = after[0]\n        end = -1\n        backslash_count = 0\n        for i, ch in enumerate(after[1:], start=1):\n            if ch == \"\\\\\":\n                backslash_count += 1\n                continue\n            if ch == quote and backslash_count % 2 == 0:\n                end = i\n                break\n            backslash_count = 0\n        if end == -1:\n            msg = f\"Unclosed {quote} in --model-params value\"\n            raise ValueError(msg)\n        # Parse the quoted token with shlex so escaped quotes are unescaped.\n        json_str = shlex.split(after[: end + 1], posix=True)[0]\n        rest = after[end + 1 :].lstrip()\n    elif after[0] == \"{\":\n        # Walk forward to find the matching closing brace.\n        depth = 0\n        end = -1\n        for i, ch in enumerate(after):\n            if ch == \"{\":\n                depth += 1\n            elif ch == \"}\":\n                depth -= 1\n                if depth == 0:\n                    end = i\n                    break\n        if end == -1:\n            msg = \"Unbalanced braces in --model-params value\"\n            raise ValueError(msg)","sourceCodeStart":1933,"sourceCodeEnd":1969,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/app.py#L1933-L1969","documentation":"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.","triggerScenarios":"Passing --model-params '\"temperature\":0.2' or '{\"temperature\":0.2} (opening quote present, closing quote missing) on the command line.","commonSituations":"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.","solutions":["Add the matching closing quote to the value: --model-params '{\"temperature\":0.2}'.","Wrap the JSON in single quotes so inner double quotes survive the shell, and avoid stray backslashes before the final quote.","Print the raw argv (or the command after shell expansion) to confirm the value retains both quotes."],"exampleFix":"# before (closing quote eaten by nested shell quoting)\ndcode --model-params \"{'temperature':0.2}\n\n# after\ndcode --model-params '{\"temperature\":0.2}'","handlingStrategy":"try-catch","validationCode":"value = raw.split(None, 1)[1].strip() if len(raw.split(None, 1)) > 1 else ''\nif value[:1] in {'\\'', '\"'} and value[-1:] != value[0]:\n    raise SystemExit(f\"unclosed quote in --model-params value\")","typeGuard":null,"tryCatchPattern":"try:\n    handle_command(argv)\nexcept ValueError as e:\n    if \"Unclosed\" in str(e):\n        print(\"quote the JSON with matching single quotes: --model-params '{...}'\")\n        sys.exit(2)\n    raise","preventionTips":["Use single outer quotes; let double quotes live inside the JSON.","Avoid backslash-escaping the final quote of the value.","Test the exact command string with echo before running it in scripts."],"tags":["cli","argument-parsing","quoting","shell"],"backgroundTag":"unbalanced-quote-cli-arg","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}