pypa/pip · error · InstallationError

[dependency-groups] table was malformed in

Error message

[dependency-groups] table was malformed in {path}. Cannot resolve '--group' option.

What it means

The pyproject.toml has a 'dependency-groups' key but its value is not a TOML table (dict). The resolver checks isinstance(raw_dependency_groups, dict) and rejects arrays, strings, numbers, or inline tables used incorrectly. The [dependency-groups] table must be a mapping of group names to requirement lists.

Solutions

  1. Use TOML section header syntax: '[dependency-groups]' followed by 'groupname = ["pkg1", "pkg2"]'
  2. Ensure the dependency-groups value is a dict/table, not an array or scalar

Example fix

# before — pyproject.toml
dependency-groups = ["pytest", "ruff"]

# after
[dependency-groups]
dev = ["pytest", "ruff"]
Defensive patterns

Strategy: validation

Validate before calling

from pip._internal.utils.compat import tomllib

def is_dependency_groups_well_formed(path: str) -> bool:
    with open(path, "rb") as fp:
        data = tomllib.load(fp)
    return isinstance(data.get("dependency-groups"), dict)

if not is_dependency_groups_well_formed("pyproject.toml"):
    print("[dependency-groups] must be a TOML table, not an array or string")

Type guard

from pip._internal.utils.compat import tomllib

def is_valid_dependency_groups_table(path: str) -> bool:
    """Type guard: True if dependency-groups is a dict/table."""
    with open(path, "rb") as fp:
        data = tomllib.load(fp)
    return isinstance(data.get("dependency-groups"), dict)

Try / catch

from pip._internal.exceptions import InstallationError
from pip._internal.req.req_dependency_group import parse_dependency_groups

try:
    reqs = parse_dependency_groups([("pyproject.toml", "dev")])
except InstallationError as e:
    if "malformed" in str(e):
        print("Use TOML section header [dependency-groups], not key = value")
    else:
        raise

Prevention

When it happens

Trigger: Writing 'dependency-groups = ["pytest"]' (array value) or 'dependency-groups = "dev"' (string value) instead of a proper TOML table with [dependency-groups] as a section header.

Common situations: Confusion between TOML table syntax (section header [dependency-groups]) and key-value syntax (dependency-groups = ...). Migrating from an array-based custom convention.

Understand the failure class

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/863b4fad3d277284. Report an issue: GitHub.

Appendix: source

Thrown at src/pip/_internal/req/req_dependency_group.py:55

                f"from '{path}': {'; '.join(messages)}"
            ) from eg


def _build_resolvers(paths: Iterable[str]) -> dict[str, Any]:
    resolvers = {}
    for path in paths:
        if path in resolvers:
            continue

        pyproject = _load_pyproject(path)
        if "dependency-groups" not in pyproject:
            raise InstallationError(
                f"[dependency-groups] table was missing from '{path}'. "
                "Cannot resolve '--group' option."
            )
        raw_dependency_groups = pyproject["dependency-groups"]
        if not isinstance(raw_dependency_groups, dict):
            raise InstallationError(
                f"[dependency-groups] table was malformed in {path}. "
                "Cannot resolve '--group' option."
            )

        try:
            resolvers[path] = DependencyGroupResolver(raw_dependency_groups)
        except ExceptionGroup as eg:
            # Handle ExceptionGroup from resolver initialization
            messages = [str(e) for e in eg.exceptions]
            raise InstallationError(
                f"[dependency-groups] data was invalid in {path}: {'; '.join(messages)}"
            ) from eg

    return resolvers


def _load_pyproject(path: str) -> dict[str, Any]:
    """

View on GitHub (pinned to f399c37189)