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

  1. pip install 'caveman-middleware[langchain]'
  2. Or install langchain-core directly: pip install langchain-core
  3. 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

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


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)