{"record":{"id":"3c7b66a5da964a62","repo":"BerriAI/litellm","slug":"mock-completion-response-failed-e","errorCode":null,"errorMessage":"Mock completion response failed - {e}","messagePattern":"Mock completion response failed - (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"litellm/main.py","lineNumber":977,"sourceCode":"            _, custom_llm_provider, _, _ = litellm.utils.get_llm_provider(model=model)\n            model_response._hidden_params[\"custom_llm_provider\"] = custom_llm_provider\n        except Exception:\n            # dont let setting a hidden param block a mock_respose\n            pass\n\n        if logging is not None:\n            logging.post_call(\n                input=messages,\n                api_key=\"my-secret-key\",\n                original_response=\"my-original-response\",\n            )\n\n        return model_response\n\n    except Exception as e:\n        if isinstance(e, openai.APIError):\n            raise e\n        raise Exception(f\"Mock completion response failed - {e}\")\n\n\n_OPENAI_DEFAULT_API_BASE: Final = \"https://api.openai.com/v1\"\n\n\ndef _resolve_openai_api_base(api_base: str | None) -> str:\n    \"\"\"Effective OpenAI base a chat request will hit: arg > global > env > default. The bridge gate\n    and the ``_complete_custom_openai`` chat handler MUST resolve this identically, or a custom base\n    set via ``litellm.api_base`` or ``OPENAI_BASE_URL``/``OPENAI_API_BASE`` is invisible to the gate,\n    which then misreads it as the default OpenAI endpoint and bridges a request the backend can't serve.\"\"\"\n    return (\n        api_base\n        or litellm.api_base\n        or get_secret_str(\"OPENAI_BASE_URL\")\n        or get_secret_str(\"OPENAI_API_BASE\")\n        or _OPENAI_DEFAULT_API_BASE\n    )\n","sourceCodeStart":959,"sourceCodeEnd":995,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/main.py#L959-L995","documentation":"Wrapper exception from the mock-response path of completion: when mock_response is supplied, litellm builds a fake ModelResponse instead of calling a provider, and any exception raised while doing so (a mock callable that throws, unexpected mock_return shape, failing logging hooks) is re-raised as Exception('Mock completion response failed - {e}'). openai.APIError is the one exception re-raised unchanged.","triggerScenarios":"Passing mock_response as a callable (lambda **kwargs: ...) that itself raises -- e.g. it indexes a kwarg the mock path did not pass; or mock_return values whose type the mock builder cannot serialize into ModelResponse.","commonSituations":"Unit tests with handwritten mock callables that assume kwargs which changed between litellm versions; mocks shared across sync and async paths; a custom logging callback failing inside post_call during tests.","solutions":["Read the inner error after the dash -- it names the real exception from your mock; fix that (usually a missing kwarg or wrong return type)","Make mock callables defensive: accept **kwargs and return a plain string or the documented mock structure","Pin/upgrade litellm deliberately so mock-path kwargs your callable depends on do not change mid-project","If you did not intend mocking, remove the mock_response kwarg leaking in from test fixtures"],"exampleFix":"# before\nlitellm.completion(model='gpt-4o', messages=m, mock_response=lambda **kw: kw['tools'][0])  # KeyError -> Mock completion response failed\n\n# after: defensive mock\nlitellm.completion(model='gpt-4o', messages=m, mock_response=lambda **kw: 'mocked text')","handlingStrategy":"try-catch","validationCode":"# keep mock callables total: never index kwargs, always return a plain value\nmock = lambda **kw: 'mocked response'  # instead of kw['messages'][0]","typeGuard":"def is_safe_mock(mock) -> bool:\n    return isinstance(mock, str) or (callable(mock) and 'kwargs' in mock.__code__.co_varnames)","tryCatchPattern":"try:\n    resp = litellm.completion(model='gpt-4o', messages=m, mock_response=my_mock)\nexcept Exception as e:\n    if str(e).startswith('Mock completion response failed'):\n        # the suffix after ' - ' is your mock's real exception; fix the mock, not litellm\n        pytest.fail(f'broken mock fixture: {e}')\n    raise","preventionTips":["Write mock callables as lambda **kw: 'text' -- accept anything, return a plain string","Do not depend on exact kwargs passed to mocks; litellm versions change the mock-path signature","Keep mock_response fixtures in one module so a litellm upgrade fixes them in one place","Assert mocks in unit tests by calling them directly with sample kwargs before wiring them into litellm"],"tags":["mock","testing","mock-response","litellm"],"backgroundTag":"mock-response-failure","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}