{"record":{"id":"d81fb3420325ee6f","repo":"OpenBMB/ChatDev","slug":"args-entries-must-be-strings","errorCode":null,"errorMessage":"args entries must be strings","messagePattern":"args entries must be strings","errorType":"validation","errorClass":"ConfigError","httpStatus":null,"severity":"error","filePath":"entity/configs/node/tooling.py","lineNumber":512,"sourceCode":"            name=\"cache_ttl\",\n            display_name=\"Tool Cache TTL\",\n            type_hint=\"float\",\n            required=False,\n            description=\"Seconds to cache MCP tool list; 0 disables cache for hot updates\",\n            advance=True,\n        ),\n    }\n\n    @classmethod\n    def from_dict(cls, data: Mapping[str, Any], *, path: str) -> \"McpLocalConfig\":\n        mapping = require_mapping(data, path)\n        command = require_str(mapping, \"command\", path)\n        args_raw = ensure_list(mapping.get(\"args\"))\n        normalized_args: List[str] = []\n        for idx, arg in enumerate(args_raw):\n            arg_path = extend_path(path, f\"args[{idx}]\")\n            if not isinstance(arg, str):\n                raise ConfigError(\"args entries must be strings\", arg_path)\n            normalized_args.append(arg)\n\n        cwd = optional_str(mapping, \"cwd\", path)\n        inherit_env = optional_bool(mapping, \"inherit_env\", path, default=True)\n        if inherit_env is None:\n            inherit_env = True\n\n        env_mapping = mapping.get(\"env\")\n        if env_mapping is not None:\n            if not isinstance(env_mapping, Mapping):\n                raise ConfigError(\"env must be a mapping\", extend_path(path, \"env\"))\n            env = {str(k): str(v) for k, v in env_mapping.items()}\n        else:\n            env = {}\n\n        timeout_value = mapping.get(\"startup_timeout\", 10.0)\n        if timeout_value is None:\n            startup_timeout = 10.0","sourceCodeStart":494,"sourceCodeEnd":530,"githubUrl":"https://github.com/OpenBMB/ChatDev/blob/4fb2db0ea90375ce1059f44fe03ffbd191a7a169/entity/configs/node/tooling.py#L494-L530","documentation":"Raised by the stdio-process tooling config parser when the 'args' list contains an entry that is not a string. Args are the argv passed to the spawned command; only strings are accepted.","triggerScenarios":"args: [\"--port\", 8080] in a tooling config with a command like 'npx'; booleans (true) intended as flags; nested lists.","commonSituations":"Writing args: [--verbose] in YAML (becomes bool or null); JSON configs generated from Python lists with ints; passing flags as true instead of \"--verbose\".","solutions":["Quote every arg: \"--port\", \"8080\"","Express boolean flags as their flag string (\"--verbose\") not true/false","Run [str(a) for a in args] before from_dict when args are programmatically built"],"exampleFix":"# before\nargs: [\"--port\", 8080]\n# after\nargs: [\"--port\", \"8080\"]","handlingStrategy":"type-guard","validationCode":"args = cfg.get(\"args\", [])\nassert all(isinstance(a, str) for a in args)","typeGuard":"def valid_args(v) -> bool:\n    return isinstance(v, list) and all(isinstance(a, str) for a in v)","tryCatchPattern":"except ConfigError as e:\n    if \"args entries\" in str(e):\n        cfg[\"args\"] = [str(a) for a in cfg[\"args\"]]","preventionTips":["Quote CLI numbers in YAML: \"8080\" not 8080","Express flags as \"--verbose\", never true/false","Stringify programmatically built argv lists"],"tags":["config","validation","args","subprocess","tooling"],"backgroundTag":"config-type-validation-failed","analyzedSha":"4fb2db0ea90375ce1059f44fe03ffbd191a7a169","analyzedAt":"2026-08-27T14:35:29.622Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}