# Risk map — langchain-ai/langchain

> Canonical page: https://codevetter.com/unpack/langchain/risk-map

# Risk map — langchain-ai/langchain

Scanned commit 9e4ea7a3495992c02a79de6fa5788e028b03df11 (2026-09-22). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

The highest blast radius sits in places that execute or reach out: ShellToolMiddleware spawns real subprocesses (host/docker/codex policies), MCPAdapter intentionally blocks non-http(s) string targets because FastMCP would otherwise exec local files, and core's _security module provides SSRF validation with a test-only bypass env var. Fragile spots: regex-based model capability fallbacks that must track provider releases, a 9_999 recursion limit, deferred import errors from lazy provider loading, validation gaps when wrap_tool_call middleware exists, and the still-shipped langchain-classic legacy surface.
- ShellToolMiddleware executes model-generated shell commands via subprocess.Popen (n noqa'd S603); HostExecutionPolicy runs commands directly on the host — DockerExecutionPolicy/CodexSandboxExecutionPolicy exist precisely because host execution is dangerous. Agents given this middleware have arbitrary-code-execution capability. — [libs/langchain_v1/langchain/agents/middleware/_execution.py#L27-140](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/_execution.py#L27-L140) [libs/langchain_v1/langchain/agents/middleware/shell_tool.py#L59-120](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/shell_tool.py#L59-L120)
- MCPAdapter._validate_url_target rejects any str target that is not http/https because fastmcp.Client tests strings as filesystem paths first and would launch a matching .py/.js file as a subprocess — a deliberate guard against config/model-supplied strings becoming local code execution. — [libs/langchain_v1/langchain/mcp/adapter.py#L84-122](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/mcp/adapter.py#L84-L122)
- core._security provides SSRF protection (validate_safe_url) blocking private IPs, localhost, cloud metadata, and k8s-internal addresses — but a `LANGCHAIN_ENV=local_test` env var bypasses validation for hostnames starting with 'test' containing 'server', a foot-gun if set in production. — [libs/core/langchain_core/_security/_ssrf_protection.py#L29-80](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/core/langchain_core/_security/_ssrf_protection.py#L29-L80) [libs/core/langchain_core/_security/_policy.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/core/langchain_core/_security/_policy.py)
- FALLBACK_MODELS_WITH_STRUCTURED_OUTPUT is a hand-maintained regex list of model names assumed to support provider-native structured output when profile data is missing — it will silently mispredict capabilities for new models until updated. — [libs/langchain_v1/langchain/agents/factory.py#L174-194](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L174-L194)
- The compiled agent gets `recursion_limit: 9_999` (working around a langgraph issue), so a model stuck in a tool-call loop can iterate ~10k times before stopping — cost/runaway risk mitigated only by opt-in ModelCallLimitMiddleware/ToolCallLimitMiddleware. — [libs/langchain_v1/langchain/agents/factory.py#L1829-1831](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1829-L1831) [libs/langchain_v1/langchain/agents/middleware/model_call_limit.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/model_call_limit.py)
- Lazy provider loading means ImportError surfaces at first use, not import time: `_import_module` rewrites failures into 'pip install <pkg>' messages, and ollama has a langchain_community fallback that can mask which package is actually missing. — [libs/langchain_v1/langchain/chat_models/base.py#L123-191](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/chat_models/base.py#L123-L191)
- Client-side tool validation in `_get_bound_model` is skipped entirely when any middleware defines wrap_tool_call, so a typo'd dynamic tool name fails only when the middleware's own handler misses it — validation coverage depends on middleware correctness. — [libs/langchain_v1/langchain/agents/factory.py#L1317-1345](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1317-L1345)
- wrap_model_call middleware cannot return Command.goto (raises NotImplementedError pointing users at jump_to), and commands accumulate inner-first through the composed stack — ordering/return-shape mistakes produce runtime errors deep in the loop. — [libs/langchain_v1/langchain/agents/factory.py#L244-250](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L244-L250) [libs/langchain_v1/langchain/agents/factory.py#L67-80](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L67-L80)
- langchain-classic remains a large shipped legacy surface (chains/, agents/, retrievers/, utilities/ including many network-calling API wrappers); the dangerous LLMBashChain was removed — its module is now a stub raising AttributeError redirecting to langchain-experimental. — [libs/langchain/langchain_classic/chains/llm_bash/__init__.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain/langchain_classic/chains/llm_bash/__init__.py) [libs/langchain/langchain_classic/agents/agent.py#L1012](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain/langchain_classic/agents/agent.py#L1012)
- PIIMiddleware mutates streamed content in flight via _PIIStreamTransformer — silent redaction means downstream consumers (logs, users) see altered text; a false-positive detection corrupts model output with no record unless tracing is on. (inferred) — [libs/langchain_v1/langchain/agents/middleware/pii.py#L39-66](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/pii.py#L39-L66)
- Unit tests for persistence require live postgres/redis containers — a contributor running plain pytest without `make test`'s docker compose step will hit connection failures, not skips. (inferred) — [libs/langchain_v1/Makefile#L10-44](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/Makefile#L10-L44) [libs/langchain_v1/tests/unit_tests/agents/conftest_checkpointer.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/tests/unit_tests/agents/conftest_checkpointer.py)
- init_chat_model's 'langsmith' provider silently rewrites kwargs (openai_api_base -> gateway.smith.langchain.com, api key from LANGSMITH_GATEWAY_API_KEY/LANGSMITH_API_KEY, use_responses_api=True) — credentials and traffic routing change based on env vars. — [libs/langchain_v1/langchain/chat_models/base.py#L24-38](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/chat_models/base.py#L24-L38)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
