JuliusBrussee/caveman · error · ImportError

Install caveman-middleware[pydantic-ai] to use the Pydantic…

Error message

Install caveman-middleware[pydantic-ai] to use the Pydantic AI adapter

What it means

The Pydantic AI adapter is an optional extra of caveman-middleware. At import time the module tries to import pydantic_ai; if the package is absent it converts the ModuleNotFoundError into an actionable ImportError telling you which extra to install.

Solutions

  1. Run `pip install 'caveman-middleware[pydantic-ai]'`
  2. If you do not use Pydantic AI, remove the import of caveman_middleware.pydantic_ai from your code path
  3. Pin the extra in requirements/pyproject so deployment environments include it

Example fix

// before
pip install caveman-middleware
// after
pip install 'caveman-middleware[pydantic-ai]'
Defensive patterns

Strategy: try-catch

Validate before calling

import importlib.util
if importlib.util.find_spec("pydantic_ai") is None:
    raise SystemExit("Install caveman-middleware[pydantic-ai]")

Try / catch

try:
    from caveman_middleware import pydantic_ai
except ImportError as e:
    if "pydantic-ai" in str(e):
        logging.error("Run: pip install 'caveman-middleware[pydantic-ai]'")
    raise

Prevention

When it happens

Trigger: importing caveman_middleware.pydantic_ai (or anything that imports it) in an environment where the pydantic_ai distribution is not installed, e.g. after `pip install caveman-middleware` without extras.

Common situations: Fresh CI or container images built without optional extras; deploying to a slim runtime image that omits dev dependencies; a dependency bump that dropped the [pydantic-ai] extra.

Understand the failure class

Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/e8d9dcbb619752b7. Report an issue: GitHub.

Appendix: source

Thrown at packages/middleware/python/caveman_middleware/pydantic_ai.py:25

import uuid
from contextlib import asynccontextmanager
from dataclasses import replace
from importlib.metadata import version
from typing import Any

try:
    from pydantic_ai import RunContext, Tool
    from pydantic_ai.capabilities import AbstractCapability
    from pydantic_ai.messages import (
        ModelMessage, ModelMessagesTypeAdapter, ModelRequest, ModelResponse,
        ToolCallPart, ToolReturnPart,
    )
    from pydantic_ai.models import Model, ModelRequestContext, ModelRequestParameters
    from pydantic_ai.models.wrapper import WrapperModel
    from pydantic_ai.toolsets import FunctionToolset
    from pydantic_core import PydanticSerializationError
except ModuleNotFoundError as error:
    raise ImportError("Install caveman-middleware[pydantic-ai] to use the Pydantic AI adapter") from error

from caveman_cloud.middleware import Adapter, Candidate, MiddlewareError, MiddlewareRuntime, Scope
from caveman_cloud.middleware.runtime import RECOVERY_DESCRIPTION, RECOVERY_SCHEMA
from ._native import Attempt, manifest, owner
from ._versions import supports_framework

ADAPTER = Adapter("pydantic-ai", "0.1.0", "2.42.0", "pydantic-ai-message-v1")


def scope_from_run(ctx: RunContext, *, namespace: str) -> Scope:
    """Use native conversation identity plus application-owned branch metadata."""
    if not isinstance(ctx.conversation_id, str) or not ctx.conversation_id:
        raise ValueError("Pydantic AI middleware requires a native conversation_id")
    metadata = ctx.metadata or {}
    return Scope(namespace, ctx.conversation_id, metadata.get("caveman_branch_id", "main"),
                 metadata.get("caveman_cache_epoch", "0"))

View on GitHub (pinned to 3ee70a1026)