OpenBMB/ChatDev · error · ValueError
package entries must be strings
Error message
package entries must be strings
What it means
install_python_packages validates every entry in its packages list and requires each to be a string. Non-string entries (None, numbers, lists/dicts from malformed JSON) raise ValueError before any uv command runs. This front-loads type validation so bad payloads fail fast.
Source
Thrown at functions/function_calling/uv_related.py:68
raise ValueError("python_workspace_root missing from _context")
path = Path(raw_path).expanduser().resolve()
path.mkdir(parents=True, exist_ok=True)
return path
def resolve_under_workspace(self, relative_path: str | Path) -> Path:
candidate = Path(relative_path)
absolute = candidate if candidate.is_absolute() else self.workspace_root / candidate
absolute = absolute.expanduser().resolve()
if self.workspace_root not in absolute.parents and absolute != self.workspace_root:
raise ValueError("script path is outside workspace root")
return absolute
def _validate_packages(packages: Sequence[str]) -> List[str]:
normalized: List[str] = []
for pkg in packages:
if not isinstance(pkg, str):
raise ValueError("package entries must be strings")
stripped = pkg.strip()
if not stripped:
raise ValueError("package names cannot be empty")
if not _SAFE_PACKAGE_RE.match(stripped):
raise ValueError(f"unsafe characters detected in package spec {pkg}")
if stripped.startswith("-"):
raise ValueError(f"flags are not allowed in packages list: {pkg}")
normalized.append(stripped)
if not normalized:
raise ValueError("at least one package is required")
return normalized
def _coerce_timeout_seconds(timeout_seconds: Any) -> float | None:
if timeout_seconds is None:
return None
if isinstance(timeout_seconds, bool):
raise ValueError("timeout_seconds must be a number")View on GitHub (pinned to 4fb2db0ea9)
Solutions
- Ensure every packages entry is a str
- Validate/cast entries (e.g. str(p) only when sensible) before calling
- Add a JSON schema requiring items.type=string for the packages array in your tool definition
Example fix
# before install_python_packages(packages=["numpy", 42]) # after install_python_packages(packages=["numpy", "pydantic"])
Defensive patterns
Strategy: type-guard
Validate before calling
packages = [p for p in packages if isinstance(p, str) and p.strip()] install_python_packages(packages=packages, _context=ctx)
Type guard
def all_strings(items) -> bool:
return all(isinstance(i, str) for i in items) Try / catch
try:
install_python_packages(packages=packages, _context=ctx)
except ValueError as e:
if "must be strings" in str(e):
packages = [str(p) for p in packages if p]
install_python_packages(packages=packages, _context=ctx)
else:
raise Prevention
- Schema-require packages as array of strings
- Filter/cast mixed-type lists at the boundary
- Never build the list from untyped user input directly
When it happens
Trigger: Passing packages=["numpy", 42] or packages=[None]; JSON tool args where an element is a number or nested object; unpacking a tuple/iterable of mixed types into the list.
Common situations: LLM tool-call payloads with mixed-type arrays; config files parsed without schema validation; programmatic lists built from untyped inputs.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- package names cannot be empty
- each edit entry must be a mapping object
- end_line must be an integer
- replacement must be a string
- unsafe characters detected in package spec {pkg}
AI-assisted analysis of OpenBMB/ChatDev@4fb2db0ea9 (2026-08-27).
Data as JSON: /api/errors/eb2f8b495064e4f6.
Report an issue: GitHub.