{"record":{"id":"a426c4f50cb8486e","repo":"langchain-ai/deepagents","slug":"failed-to-parse-server-env-prefix-suffix-as-jso","errorCode":null,"errorMessage":"Failed to parse {SERVER_ENV_PREFIX}{suffix} as JSON: {exc}. Value was: {raw[:200]!r}","messagePattern":"Failed to parse (.+?)(.+?) as JSON: (.+?)\\. Value was: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/_server_config.py","lineNumber":70,"sourceCode":"        suffix: Variable name suffix after the `DEEPAGENTS_CODE_SERVER_` prefix.\n\n    Returns:\n        Parsed JSON value, or `None` if the variable is absent.\n\n    Raises:\n        ValueError: If the variable is present but not valid JSON.\n    \"\"\"\n    raw = os.environ.get(f\"{SERVER_ENV_PREFIX}{suffix}\")\n    if raw is None:\n        return None\n    try:\n        return json.loads(raw)\n    except json.JSONDecodeError as exc:\n        msg = (\n            f\"Failed to parse {SERVER_ENV_PREFIX}{suffix} as JSON: {exc}. \"\n            f\"Value was: {raw[:200]!r}\"\n        )\n        raise ValueError(msg) from exc\n\n\ndef _read_env_str_list(suffix: str) -> tuple[str, ...]:\n    raw = _read_env_json(suffix)\n    if raw is None:\n        return ()\n    if isinstance(raw, list) and all(isinstance(item, str) for item in raw):\n        return tuple(raw)\n    msg = f\"Invalid {SERVER_ENV_PREFIX}{suffix}: expected a JSON string list\"\n    raise ValueError(msg)\n\n\ndef _read_env_allow_fs_tools() -> list[FsToolName] | None:\n    \"\"\"Read and shape-validate the `ALLOW_FS_TOOLS` filesystem allowlist.\n\n    The parent writes only an absent variable (unrestricted — `None`, which is\n    also what `--allow-fs-tools all` collapses to) or a non-empty JSON list of\n    tool names (`main._parse_allow_fs_tools_flag`). This runs in the server","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/_server_config.py#L52-L88","documentation":"`_read_env_json` in `libs/code/deepagents_code/_server_config.py` raises this `ValueError` when a `DEEPAGENTS_CODE_SERVER_*` environment variable is present but its value is not valid JSON. The server subprocess reads structured configuration (string lists, booleans with JSON shapes, allowlists) from the environment, and the message includes the parser error plus the first 200 characters of the raw value to make the offending input diagnosable. It fails closed because some of these variables are security controls.","triggerScenarios":"Setting `DEEPAGENTS_CODE_SERVER_*` variables (e.g. `DEEPAGENTS_CODE_SERVER_ALLOW_FS_TOOLS` or any suffix consumed by `_read_env_json` via `_read_env_str_list`, `_read_env_allow_fs_tools`, or `ServerConfig.from_env`) to non-JSON text such as `grep,glob` (no JSON quotes/brackets), single-quoted JSON `'['a']'` where the shell strips quotes leaving bare `[a]`, or trailing commas/garbage.","commonSituations":"Hand-editing an exported variable in a shell profile without JSON-encoding it; a parent process writing the variable with an unescaped/undecoded payload; copy-pasting a Python list literal `[a, b]` (unquoted items) instead of a JSON array; template rendering inserting raw text into the value.","solutions":["Set the variable to valid JSON, e.g. `export DEEPAGENTS_CODE_SERVER_ALLOW_FS_TOOLS='[\"grep\",\"glob\"]'` (single-quote so the shell preserves double quotes).","Validate locally first: `python -c \"import json,os;json.loads(os.environ['DEEPAGENTS_CODE_SERVER_...'])\"` to confirm the exact value parses.","Check the raw value shown in the error message (`Value was: ...`) for shell quote-stripping, truncation, or embedded newlines.","Unset the variable to fall back to the default behavior if you did not intend to configure it.","Fix the parent/launcher code that writes the variable so it JSON-encodes with `json.dumps` before export."],"exampleFix":"// before (shell)\nexport DEEPAGENTS_CODE_SERVER_ALLOW_FS_TOOLS=grep,glob\n// after (shell)\nexport DEEPAGENTS_CODE_SERVER_ALLOW_FS_TOOLS='[\"grep\",\"glob\"]'","handlingStrategy":"validation","validationCode":"import json, os\n\ndef env_json_valid(suffix: str) -> bool:\n    raw = os.environ.get(f\"DEEPAGENTS_CODE_SERVER_{suffix}\")\n    if raw is None:\n        return True\n    try:\n        json.loads(raw)\n        return True\n    except json.JSONDecodeError:\n        return False","typeGuard":"def is_json_object(raw: str) -> bool:\n    try:\n        return isinstance(json.loads(raw), object)\n    except json.JSONDecodeError:\n        return False","tryCatchPattern":"try:\n    config = ServerConfig.from_env()\nexcept ValueError as exc:\n    raise ConfigError(f\"malformed DEEPAGENTS_CODE_SERVER_* variable: {exc}\") from exc","preventionTips":["Build env values with json.dumps() in the launching process, never by string formatting.","Single-quote JSON in shell so inner double quotes survive.","Test-parse every DEEPAGENTS_CODE_SERVER_* variable in CI before spawning the server.","Read the 'Value was:' excerpt in the error to spot shell quote-stripping or truncation."],"tags":["json","environment","configuration","parsing"],"backgroundTag":"invalid-env-json","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}