JuliusBrussee/caveman · error · ImportError

Install caveman-middleware[strands] to use the Strands…

Error message

Install caveman-middleware[strands] to use the Strands adapter

What it means

The Strands adapter is an optional extra. The module imports strands at import time; if the strands distribution is missing, the ModuleNotFoundError is re-raised as an ImportError naming the extra to install.

Solutions

  1. Run `pip install 'caveman-middleware[strands]'`
  2. Remove the strands adapter import if Strands is not used in this service
  3. Add the extra to your dependency manifest so all environments install it

Example fix

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

Strategy: try-catch

Validate before calling

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

Try / catch

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

Prevention

When it happens

Trigger: Importing caveman_middleware.strands (or a bundle module that imports it) in an environment where `strands-agents`/strands is not installed, e.g. plain `pip install caveman-middleware`.

Common situations: CI runners with only base requirements; serverless images trimmed of extras; onboarding docs followed without the [strands] extra; a move from a monorepo dev env to a clean production env.

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/76c9738e308c8b01. Report an issue: GitHub.

Appendix: source

Thrown at packages/middleware/python/caveman_middleware/strands.py:15

"""Strands native Model delegate, including the structured-output hook gap."""
from __future__ import annotations

import asyncio
import json
import uuid
import weakref

try:
    from strands import tool
    from strands.models.model import Model
    from strands.plugins import Plugin
    from strands.types.tools import ToolContext
except ModuleNotFoundError as error:
    raise ImportError("Install caveman-middleware[strands] to use the Strands adapter") from error

from caveman_cloud.middleware import Adapter, Candidate, MiddlewareRuntime, Scope
from caveman_cloud.middleware.runtime import RECOVERY_DESCRIPTION, RECOVERY_SCHEMA
from ._native import Attempt, manifest, owner, plain, replace_path
from ._versions import matches_framework
from ._usage import usage

ADAPTER = Adapter("strands", "0.1.0", "1.55.0", "strands-content-v1")


def _scope(source, state):
    scope = source if isinstance(source, Scope) else source(state or {})
    if not isinstance(scope, Scope):
        raise TypeError("Strands scope resolver must return a Caveman Scope")
    return scope


class CavemanModel(Model):

View on GitHub (pinned to 3ee70a1026)