langchain-ai/deepagents · error · ToolRequirementIntrospectionError

uv tool receipt contains an invalid `[tool].python` value

Error message

uv tool receipt contains an invalid `[tool].python` value

What it means

The `[tool].python` key exists in the receipt but is not a usable version string (empty or non-string). _uv_tool_python returns None when the key is absent (allowed), but raises when it is present yet invalid.

Source

Thrown at libs/code/deepagents_code/update_check.py:3007

        The recorded `[tool].python` value, or `None` when the receipt does not
            pin an interpreter.

    Raises:
        ToolRequirementIntrospectionError: If the receipt cannot be read, parsed,
            or safely re-expressed as a `--python` value.
    """
    if data is None:
        data = _uv_tool_receipt_data(tool_root)
    tool = data.get("tool")
    if not isinstance(tool, dict):
        msg = "uv tool receipt is missing `[tool]`"
        raise ToolRequirementIntrospectionError(msg)
    python = tool.get("python")
    if python is None:
        return None
    if not isinstance(python, str) or not python:
        msg = "uv tool receipt contains an invalid `[tool].python` value"
        raise ToolRequirementIntrospectionError(msg)
    return python


def _uv_tool_selected_extras(
    *,
    distribution_name: str = "deepagents-code",
    tool_root: Path | None = None,
    data: dict[str, Any] | None = None,
) -> set[NormalizedName]:
    """Return extras explicitly selected on the uv tool requirement.

    Args:
        distribution_name: Main tool distribution whose extras to read.
        tool_root: Optional uv tool environment root. Defaults to `sys.prefix`.
        data: Optional pre-parsed receipt contents. Supplied by callers that
            read several receipt fields at once so the file is parsed once
            rather than per field.

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Set `python` to a quoted version string: `python = "3.12"`.
  2. Regenerate the receipt with `uv tool install deepagents-code --force --python 3.12`.
  3. If you don't need a pinned python, remove the key entirely rather than leaving it empty.

Example fix

// before
 [tool]
 python = 3.12
// after
 [tool]
 python = "3.12"
Defensive patterns

Strategy: validation

Validate before calling

import tomllib

def python_value_ok(data: dict) -> bool:
    tool = data.get('tool') or {}
    py = tool.get('python')
    return py is None or (isinstance(py, str) and bool(py))

Type guard

def is_valid_python_pin(value: object) -> bool:
    return isinstance(value, str) and bool(value)

Try / catch

try:
    python = _uv_tool_python()
except ToolRequirementIntrospectionError:
    python = None  # ignore bad pin, use default

Prevention

When it happens

Trigger: _uv_tool_python reads tool.get("python") and finds a non-string truthy-but-invalid value (e.g. inline table, number, empty string), reached via _uv_tool_install_command.

Common situations: Receipt hand-edited with `python = 3.12` (number, not string) or `python = ""`; a receipt produced by tooling that wrote the wrong type; corruption during editing.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/978c2430f05eeca9. Report an issue: GitHub.