JuliusBrussee/caveman · error · ImportError
Install caveman-middleware[langchain] to use the LangChain…
Error message
Install caveman-middleware[langchain] to use the LangChain adapter
What it means
The LangChain adapter imports langchain_core at module import time and converts ModuleNotFoundError into this ImportError. It exists so users get a clear instruction instead of a raw langchain_core traceback. The optional extra 'langchain' bundles langchain-core as a dependency.
Solutions
- pip install 'caveman-middleware[langchain]'
- Or install langchain-core directly: pip install langchain-core
- Verify the same interpreter/venv is used (pip show langchain-core; which python).
Example fix
// before pip install caveman-middleware import caveman_middleware.langchain # ImportError // after pip install 'caveman-middleware[langchain]' import caveman_middleware.langchain # ok
Defensive patterns
Strategy: try-catch
Validate before calling
import importlib.util
if importlib.util.find_spec('langchain_core') is None:
raise SystemExit("Install with: pip install 'caveman-middleware[langchain]'") Try / catch
try:
from caveman_middleware import langchain as caveman_langchain
except ImportError:
raise SystemExit("Missing optional dependency. Run: pip install 'caveman-middleware[langchain]'") Prevention
- Always install with extras: pip install 'caveman-middleware[langchain]'.
- Pin dependencies in requirements files including extras.
- Add a CI smoke test that imports the adapter modules for every deployment image.
When it happens
Trigger: importing caveman_middleware.langchain (or any of its adapters) while langchain_core is not installed in the current environment.
Common situations: Installed caveman-middleware without [langchain] extra; deployed to a slim container image that pruned LangChain; running with a different virtualenv/interpreter than the one where LangChain was installed.
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
- Expected a native LangChain BaseChatModel
- Install caveman-middleware[anthropic] to use the Anthropic…
- Install caveman-middleware[openai] to use the OpenAI adapter
- scope resolver must return a Caveman Scope
- Synchronous LangChain calls require MiddlewareRuntime
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/6d3cfe7caca11dc8.
Report an issue: GitHub.
Appendix: source
Thrown at packages/middleware/python/caveman_middleware/langchain.py:21
import functools
import asyncio
import copy
import json
import uuid
from dataclasses import asdict
from contextlib import aclosing
try:
from langchain.agents.middleware import AgentMiddleware
from langchain_core.documents import Document, BaseDocumentCompressor
from langchain_core.language_models import BaseChatModel
from langchain_core.messages import BaseMessage, ToolMessage, convert_to_messages
from langchain_core.prompt_values import PromptValue
from langchain_core.runnables import RunnableConfig, ensure_config
from langchain_core.tools import StructuredTool
except ModuleNotFoundError as error:
raise ImportError("Install caveman-middleware[langchain] to use the LangChain adapter") from error
from caveman_cloud.middleware import Adapter, Candidate, Scope, MiddlewareRuntime, RecoveryBinding
from caveman_cloud.middleware.runtime import RECOVERY_DESCRIPTION, RECOVERY_SCHEMA
from ._native import Attempt, manifest, owner, plain
from ._versions import matches_framework
ADAPTER = Adapter("langchain", "0.1.0", "1.4.0", "langchain-message-v1")
def scope_from_config(config: RunnableConfig, *, namespace: str) -> Scope:
"""Use the caller's checkpoint thread and explicit branch/epoch identity."""
values = config.get("configurable", {})
thread = values.get("thread_id")
if not isinstance(thread, str) or not thread:
raise ValueError("LangGraph middleware requires a nonempty configurable.thread_id")
return Scope(namespace, thread, values.get("caveman_branch_id", "main"), values.get("caveman_cache_epoch", "0"))
View on GitHub (pinned to 3ee70a1026)