Back to Intelligence

LLM Tools Datasette 0.1.1: Transitive Dependency Breakage in LLM Plugins — Supply Chain Hardening Guide

SA
Security Arsenal Team
October 18, 2026
6 min read

On October 18, 2026, Simon Willison released llm-tools-datasette 0.1.1, a patch release fixing a breakage introduced when the core LLM CLI tool migrated from httpx to httpx2 in version 0.33. The failure mode is one every security engineer should recognize instantly: the plugin imported httpx without declaring it as a direct dependency, relying on it being present in the environment only because the parent tool happened to install it. When the parent dropped httpx, the plugin broke.

There is no CVE here and no active exploitation — but don't let that fool you into skipping this post. This incident is a clean, real-world demonstration of transitive dependency risk, the same class of weakness that underpins some of the most damaging supply chain compromises we've responded to over the past two years. If your security team, SOC, or data engineering function is deploying LLM tooling — and in 2026, most are — the hygiene lessons from this small breakage apply directly to how you govern AI tooling in production.

What Actually Happened

The sequence is instructive:

  1. LLM 0.33 migrated its HTTP client layer from httpx to httpx2 (the pydantic-maintained fork).
  2. The llm-tools-datasette plugin — which gives the LLM CLI tool-use capabilities against Datasette instances — imported httpx in its own code but never listed httpx in its install_requires / pyproject.toml dependencies. It was piggybacking on the fact that LLM itself pulled httpx into the environment.
  3. When LLM dropped httpx, the plugin's imports failed. The fix in 0.1.1 was to align the plugin's actual dependencies with what its code imports.

This is the benign version of the story. The adversarial version is what keeps us busy: an attacker who understands that a popular package transitively pulls in a library can target that transitive layer — via dependency confusion, typosquatting, or compromising a lightly-maintained upstream — knowing downstream consumers never audit it because it was never in their declared dependency tree.

Why Defenders Should Care About AI Tooling Dependencies Specifically

LLM CLI tools and their plugin ecosystems are proliferating across developer workstations, CI/CD pipelines, and even SOC automation workflows. These tools routinely hold:

  • API keys for commercial model providers (OpenAI, Anthropic, Gemini, Azure OpenAI)
  • Credentials and connection strings for the data sources they query — in this case, Datasette instances that may expose internal SQLite databases over HTTP
  • Execution capabilities — tool-calling plugins literally execute functions on behalf of the model, which means a compromised plugin is code execution with the user's privileges and secrets

A plugin ecosystem where components routinely rely on undeclared transitive dependencies is an ecosystem where:

  • Dependency confusion attacks become viable: publish a malicious httpx-adjacent package to a public index, and an environment with a sloppy resolver configuration may install it.
  • SBOM accuracy collapses: your software inventory says one thing, your runtime environment contains another. When the next urllib3-class vulnerability drops, you can't answer "are we affected?" in under an hour.
  • Breakage masks tampering: if users are conditioned to expect plugins to randomly break and reinstall things, an attacker-induced dependency change blends into the background noise.

Executive Takeaways

Because this is a dependency-hygiene lesson rather than an active exploit campaign, the right response is organizational and architectural — not indicator-based detection rules that would fire on every Python environment in your estate.

1. Treat LLM tooling as privileged software, not a toy. Inventory every installation of the llm CLI and similar tools (aider, openai CLI, custom wrappers) across developer endpoints and automation accounts. If a tool can hold API keys and execute tool calls, it belongs in your managed software catalog with version tracking.

2. Enforce direct dependency declaration in anything you build or fork. The root cause here was importing a package without declaring it. Mandate pip check / uv pip check in CI for internal Python projects, and consider tools like pipdeptree or deptry to flag imports that aren't declared dependencies. If you vendor or fork open-source plugins internally, apply the same standard.

3. Pin and hash-lock your LLM tooling environments. Use lockfiles (requirements.txt with --require-hashes, uv.lock, or poetry.lock) for any environment where LLM tools run with production credentials. A lockfile would not have prevented this breakage, but it makes dependency changes explicit and reviewable — which is exactly the property that defeats dependency confusion and silent upstream tampering.

4. Isolate plugin execution from credential stores. Where LLM plugins run in automation (CI jobs, scheduled agents), scope the API keys they can access to the minimum required, and prefer short-lived credentials over static keys sitting in ~/.config/llm/. A plugin that breaks loudly is fine; a plugin that fails open with broad credentials is an incident.

5. Add AI tooling to your SBOM and vuln-scanning scope. Your container and endpoint scanning should cover the Python environments where LLM CLI tools live. When a future vulnerability lands in httpx2, openai, or any model SDK, you need to know your exposure in minutes, not after a forensics engagement.

6. Monitor for unexpected package installation events in build and automation environments. Legitimate dependency churn in a locked production environment is rare. pip install events outside of sanctioned build pipelines are worth an alert — that's where dependency confusion and plugin tampering actually surface.

Remediation

For users of llm-tools-datasette:

  • Upgrade to llm-tools-datasette 0.1.1 or later. The fix declares the plugin's actual HTTP client dependency rather than relying on LLM's transitive tree.
Bash / Shell
# Verify your current plugin version
llm plugins

# Upgrade the plugin to the fixed release
llm install -U llm-tools-datasette

# Confirm the environment is consistent — no undeclared or broken deps
pip check

# Audit what the plugin actually pulls in
pipdeptree --packages llm-tools-datasette

For teams operating LLM tooling in production:

  • Rebuild locked environments after any LLM core upgrade (0.33+) and run pip check to surface exactly this class of silent breakage before it reaches production.
  • Review any internally developed LLM plugins for imports that aren't declared in pyproject.toml — this is a five-minute audit with deptry or a simple AST scan, and it directly addresses the failure mode in this release.
  • Reference the upstream release notes: llm-tools-datasette 0.1.1 and the LLM changelog for 0.33.

Bottom line: This release is a near-miss worth studying. The same undeclared-dependency pattern that caused a plugin to break this week is the pattern that causes a poisoned package to land in your environment next quarter. Fix the hygiene while the lesson is cheap.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.

LLM Tools Datasette 0.1.1: Transitive Dependency Breakage in LLM Plugins — Supply Chain Hardening Guide | Security Arsenal | Security Arsenal