OpenBMB/ChatDev · error · ValueError

flags are not allowed in packages list: {pkg}

Error message

flags are not allowed in packages list: {pkg}

What it means

After character-safety checks, _validate_packages rejects specs that begin with '-', since a leading dash would be interpreted as a command-line flag by uv (e.g. -e, --help, --requirement). This blocks argument-injection where a package entry smuggles an option into the subprocess. Note the check runs on the stripped spec, so ' -e' is caught but entries like 'pkg>-x' pattern checks happen earlier via the regex.

Source

Thrown at functions/function_calling/uv_related.py:75

        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")
    if isinstance(timeout_seconds, (int, float)):
        value = float(timeout_seconds)
    elif isinstance(timeout_seconds, str):
        raw = timeout_seconds.strip()
        if not raw:
            raise ValueError("timeout_seconds cannot be empty")
        try:

View on GitHub (pinned to 4fb2db0ea9)

Solutions

  1. Remove flag-style entries; express editable/requirements installs via a proper uv project (pyproject.toml) or the supported code path
  2. Whitelist package names (alphanumerics plus limited constraint characters) before passing user input
  3. Never interpolate raw CLI tokens into the packages list

Example fix

# before
install_python_packages(packages=["-e", "."])
# after
# editable install handled by project setup; only real specs passed
install_python_packages(packages=["numpy", "pandas"])
Defensive patterns

Strategy: validation

Validate before calling

packages = [p.strip() for p in packages if not p.strip().startswith("-")]
install_python_packages(packages=packages, _context=ctx)

Type guard

def no_flag_entries(packages) -> bool:
    return all(isinstance(p, str) and not p.strip().startswith("-") for p in packages)

Try / catch

try:
    install_python_packages(packages=packages, _context=ctx)
except ValueError as e:
    if "flags are not allowed" in str(e):
        raise ValueError(f"attempted CLI flag in packages: {e}") from e
    raise

Prevention

When it happens

Trigger: Passing packages=["-e ./pkg"] or ["--requirement", "reqs.txt"]; user input like "--help" supplied as a package name; specs beginning with a dash after whitespace stripping.

Common situations: Users trying to reuse pip/uv CLI flags (-e editable installs, -r requirements files) as package entries; injection attempts through unsanitized package fields; copy-pasting a uv pip install command and splitting all tokens into the packages list.

Related errors


AI-assisted analysis of OpenBMB/ChatDev@4fb2db0ea9 (2026-08-27). Data as JSON: /api/errors/b9c67db58a131cbc. Report an issue: GitHub.