If you tried to pass a custom http_client to ChatAnthropic and got TypeError: __init__() got an unexpected keyword argument 'http_client', you are hitting the well-known limitation tracked in GitHub issue #30146. The fix depends on which version of langchain-anthropic you run. Here is the working pattern for 2026.
Why the TypeError happens
ChatAnthropic wraps the Anthropic Python SDK but does not forward every keyword argument to the underlying client. In earlier versions, passing http_client=my_client was ignored silently. In langchain-anthropic 0.3+, the keyword raises TypeError because the wrapper became stricter about unknown kwargs. To pass a custom httpx.Client (for proxies, TLS pinning, custom timeouts), you build the anthropic client yourself and pass it via anthropic_client.
The fix: pass a pre-built anthropic client
import httpx
import anthropic
from langchain_anthropic import ChatAnthropic
# WRONG (raises TypeError in langchain-anthropic 0.3+)
# custom = httpx.Client(proxy="http://proxy.corp:8080", timeout=30)
# llm = ChatAnthropic(model="claude-opus-4-8", http_client=custom)
# CORRECT: build anthropic client with custom httpx, then pass to LangChain
custom_http = httpx.Client(
proxy="http://proxy.corp:8080",
timeout=httpx.Timeout(30.0, connect=5.0),
verify="/path/to/corp-ca-bundle.pem",
)
anth_client = anthropic.Anthropic(
http_client=custom_http,
max_retries=3,
)
llm = ChatAnthropic(
model="claude-opus-4-8",
anthropic_client=anth_client,
)
reply = llm.invoke("Hello via corporate proxy")
print(reply.content)Async variant
import httpx
import anthropic
from langchain_anthropic import ChatAnthropic
async_http = httpx.AsyncClient(
proxy="http://proxy.corp:8080",
timeout=httpx.Timeout(30.0, connect=5.0),
)
anth_async = anthropic.AsyncAnthropic(http_client=async_http)
llm = ChatAnthropic(
model="claude-opus-4-8",
anthropic_client_async=anth_async,
)
# Now llm.ainvoke() routes through the corporate proxy
reply = await llm.ainvoke("Hello async")
print(reply.content)Debugging checklist
- Check your langchain-anthropic version:
python -c "import langchain_anthropic; print(langchain_anthropic.__version__)". Behavior changed in 0.3.0. - Confirm you built the anthropic client separately, not inside ChatAnthropic. Passing
anthropic_client=is the only supported way to inject a custom httpx. - If you use async, pass to
anthropic_client_async, notanthropic_client. Missing the async client causes silent fallback to default httpx which ignores your proxy. - Test the proxy works with a bare anthropic call first:
anth_client.messages.create(...). If that fails, the LangChain wrapper cannot fix it.
Real-world example: corporate proxy with TLS pinning
import httpx
import anthropic
from langchain_anthropic import ChatAnthropic
from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated
from langgraph.graph.message import add_messages
from langchain_core.messages import HumanMessage
# Corporate httpx client with proxy + custom CA bundle
CORP_HTTP = httpx.Client(
proxy="http://user:[email protected]:8080",
timeout=httpx.Timeout(45.0, connect=10.0),
verify="/etc/ssl/corp-bundle.pem",
headers={"User-Agent": "MyApp/1.0"},
)
# Anthropic client wired to corp httpx
ANTH = anthropic.Anthropic(
http_client=CORP_HTTP,
max_retries=5,
)
# LangChain wrapper receives the pre-built client
LLM = ChatAnthropic(
model="claude-opus-4-8",
anthropic_client=ANTH,
max_tokens=2048,
)
class State(TypedDict):
messages: Annotated[list, add_messages]
def chat(state: State):
reply = LLM.invoke(state["messages"])
return {"messages": [reply]}
graph = StateGraph(State)
graph.add_node("chat", chat)
graph.set_entry_point("chat")
graph.add_edge("chat", END)
app = graph.compile()
result = app.invoke({"messages": [HumanMessage(content="Ping via corp proxy")]})
print(result["messages"][-1].content)Common mistakes with custom httpx clients
- Passing http_client directly to ChatAnthropic. Raises TypeError since 0.3. Always build the anthropic client first.
- Mixing sync and async clients. If you call ainvoke, pass anthropic_client_async. If you call invoke, pass anthropic_client. Mixing them causes silent default-fallback bugs.
- Sharing one httpx client across threads without a connection pool tune. httpx.Client is thread-safe but the default connection pool is small. Increase with
httpx.Limits(max_connections=100). - Forgetting to close the httpx client. Use context managers or explicit close on shutdown to avoid leaked file descriptors.
Debugging checklist for the SDK/library error
Before diving into fixes, run through this diagnostic checklist. Nine times out of ten the answer surfaces here.
- Read the full traceback, not just the error message. The stack trace shows exactly which line and which call chain triggered the error. The last line names the immediate cause; earlier lines show how you got there.
- Add print or debug statements just before the failing line. Print the variable, its type, and its value. Nine out of ten error surprises come from the value being different from what you assumed.
- Check Python version compatibility. Errors sometimes result from APIs that changed between versions. Run your interpreter version check and compare against the library documentation for that version.
- Isolate the failing call in a minimal reproducer. Copy the failing line into a small standalone script with hardcoded inputs. If it fails there too, the bug is in your code. If not, something in your surrounding context is contributing.
- Search the exact error message. Include the class name and the specific text in your search. Chances are someone else hit the same issue and the fix is documented on Stack Overflow or the library’s GitHub issues.
Common causes for the SDK/library error
Most instances of this error trace back to one of these root causes:
- Uninitialized or missing input. A variable was not populated before use, or the input source (file, API response, database row) did not contain the expected key or value.
- Type mismatch. The code expected a specific type (dict, list, string) but received something different. Python’s dynamic typing means this often surfaces at runtime, not at compile time.
- Version drift. The library API changed and your code assumes the old signature. Check the library’s changelog for breaking changes since the version you last used.
- Race condition or ordering issue. Async or concurrent code sometimes tries to access data before it is ready. Add awaits, locks, or explicit ordering to fix.
- Copy-paste from stale tutorial. Older tutorials may use APIs that no longer exist. Always check the official docs for the current version.
Testing and prevention
Preventing this class of error from recurring is more valuable than fixing it once. Build these habits into your workflow:
- Write tests that trigger the error path. If your test suite hits the error scenario, catch and assert it. A well-written test prevents the same bug from returning.
- Validate inputs at API boundaries. When data enters your code from external sources (HTTP requests, file uploads, database queries), validate structure and types immediately.
- Use type hints and static analysis. Tools like mypy for Python or TypeScript for JavaScript catch many type mismatches before you run the code.
- Log important state. Structured logging with context helps you debug production issues faster. Include enough context to reconstruct what happened.
- Read the library changelog. Before upgrading a dependency, skim the changelog for breaking changes. Two minutes of reading saves an hour of debugging.
When to ask for help
Some errors are worth solving yourself for the learning. Others are worth asking about early. Ask for help when: the error blocks a customer-facing feature, you have spent an hour without progress, the error involves security or data integrity, or you are unsure whether your fix will introduce new bugs. Post to Stack Overflow with a minimal reproducer, or ask a senior developer on your team. Time boxes are your friend.
Official documentation
Quick step-by-step summary (click to expand)
- Check your langchain-anthropic version. Run pip show langchain-anthropic. Versions before 0.2.0 do not accept http_client.
- Upgrade to the latest version. Run pip install –upgrade langchain-anthropic to pull the current release.
- Remove http_client from constructor. If passing http_client=httpx.Client(…), remove it. Newer versions handle the client internally.
- Pass proxy via anthropic_api_url instead. If you needed a custom proxy, set the ANTHROPIC_API_URL environment variable or the anthropic_api_url parameter.
- Verify with a small test. Run a simple ChatAnthropic(model=”claude-3-5-sonnet-latest”).invoke(“Hi”) to confirm the fix works.
Frequently Asked Questions
Why did http_client stop working in 0.3?
langchain-anthropic 0.3+ added strict kwarg validation. Previously unknown kwargs were silently ignored, which hid config bugs. The team chose to raise TypeError so misconfigured proxies fail loudly.
Can I still set a proxy without building anthropic_client?
Only via environment variables (HTTPS_PROXY, HTTP_PROXY). For per-request or per-client control, use the anthropic_client pattern.
Do I need both anthropic_client and anthropic_client_async?
Only if you use both invoke and ainvoke on the same ChatAnthropic instance. Most apps pick one mode.
Does this affect ChatOpenAI too?
Similar pattern applies. Build openai.OpenAI(http_client=…) first, then pass to ChatOpenAI via client parameter.
Any performance hit from custom httpx?
Negligible. Custom httpx is used at network layer only. Tune the connection pool (httpx.Limits) if you plan high concurrency.
