JuliusBrussee/caveman · error · ImportError
Install caveman-middleware[crewai] to use the CrewAI adapter
Error message
Install caveman-middleware[crewai] to use the CrewAI adapter
What it means
The CrewAI adapter in caveman_middleware imports optional CrewAI dependencies (crewai.llms, crewai.tools, crewai.utilities) at module import time. If CrewAI is not installed, this ImportError is raised as the cause-chained error, telling you to install the optional extra instead of a raw ModuleNotFoundError.
Solutions
- Run pip install "caveman-middleware[crewai]" to install CrewAI with the supported version range.
- Add caveman-middleware[crewai] to your requirements/pyproject dependencies and reinstall.
- Verify crewai imports directly: python -c "import crewai.llms.base_llm"; if that fails, upgrade/reinstall crewai to a version providing those submodules.
Example fix
// before pip install caveman-middleware // after pip install "caveman-middleware[crewai]"
Defensive patterns
Strategy: try-catch
Validate before calling
try:
from crewai.llms.base_llm import BaseLLM
except ModuleNotFoundError:
raise RuntimeError("Run: pip install 'caveman-middleware[crewai]'") Type guard
def crewai_extra_installed() -> bool:
import importlib.util
return importlib.util.find_spec("crewai") is not None Try / catch
try:
from caveman_middleware import crewai as caveman_crewai
except ImportError as e:
logging.error("Install the extra: pip install 'caveman-middleware[crewai]' (%s)", e)
raise Prevention
- Always install optional framework adapters with their extras (caveman-middleware[crewai]).
- Pin the extra in requirements/pyproject, not the bare package.
- Import adapter modules lazily at startup so missing extras fail fast with a clear message.
- Verify imports in CI for every deployment image.
When it happens
Trigger: Importing caveman_middleware.crewai (or any code path that imports the CrewAI adapter) in an environment where the `crewai` package (or one of its imported submodules) is missing. Triggered during `import`, before any adapter API is used.
Common situations: Installing caveman-middleware without extras (pip install caveman-middleware instead of caveman-middleware[crewai]); deploying to an environment where the extra was omitted from requirements; a CrewAI version change renaming submodules like crewai.llms.base_llm.
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
- Install caveman-middleware[agno] to use the Agno adapter
- Install caveman-middleware[google] to use the Google adapter
- cave_${harness}_upstream_version_mismatch
- cave_harness_upstream_version_mismatch
- cave_${harness}_upstream_version_unresolvable
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/a6789914dee17b48.
Report an issue: GitHub.
Appendix: source
Thrown at packages/middleware/python/caveman_middleware/crewai.py:29
import threading
import uuid
import weakref
from contextlib import ExitStack
from dataclasses import dataclass, field
from importlib.metadata import version
from typing import Any
try:
from crewai import BaseLLM
from crewai.events import LLMCallCompletedEvent, crewai_event_bus
from crewai.hooks import InterceptionPoint, on, unregister_hook
from crewai.llms.base_llm import call_stop_override, call_stream_override
from crewai.tools import BaseTool
from crewai.utilities.agent_utils import convert_tools_to_openai_schema
from crewai.utilities.string_utils import sanitize_tool_name
from pydantic import BaseModel, ConfigDict, Field, PrivateAttr
except ModuleNotFoundError as error:
raise ImportError("Install caveman-middleware[crewai] to use the CrewAI adapter") from error
from caveman_cloud.middleware import Adapter, Candidate, MiddlewareError, MiddlewareRuntime, Scope
from caveman_cloud.middleware.runtime import RECOVERY_DESCRIPTION
from ._native import Attempt, leaves, manifest, owner, plain, replace_path
from ._versions import matches_framework
from ._usage import usage
FRAMEWORK_VERSION = version("crewai")
ADAPTER = Adapter("crewai", "0.1.0", FRAMEWORK_VERSION, "crewai-messages-v1")
_call = contextvars.ContextVar("caveman_crewai_call", default=None)
class _RecoveryInput(BaseModel):
model_config = ConfigDict(extra="forbid")
handle: str = Field(pattern=r"^cmw_[a-f0-9]{48}$")
offset: int = Field(default=0, ge=0)
limit: int = Field(default=262144, ge=4, le=262144)
query: str = Field(default="", max_length=1024)View on GitHub (pinned to 3ee70a1026)