{"record":{"id":"8296fa3372be9efa","repo":"deepset-ai/haystack","slug":"the-parameter-http-client-kwargs-must-be-a-dicti","errorCode":null,"errorMessage":"The parameter 'http_client_kwargs' must be a dictionary.","messagePattern":"The parameter 'http_client_kwargs' must be a dictionary\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"haystack/utils/http_client.py","lineNumber":35,"sourceCode":") -> httpx.AsyncClient | None: ...\ndef init_http_client(\n    http_client_kwargs: dict[str, Any] | None = None, async_client: bool = False\n) -> httpx.Client | httpx.AsyncClient | None:\n    \"\"\"\n    Initialize an httpx client based on the http_client_kwargs.\n\n    :param http_client_kwargs:\n        The kwargs to pass to the httpx client.\n    :param async_client:\n        Whether to initialize an async client.\n\n    :returns:\n        A httpx client or an async httpx client.\n    \"\"\"\n    if not http_client_kwargs:\n        return None\n    if not isinstance(http_client_kwargs, dict):\n        raise TypeError(\"The parameter 'http_client_kwargs' must be a dictionary.\")\n\n    # Create a copy to avoid modifying the original dict\n    processed_kwargs = http_client_kwargs.copy()\n\n    # Handle limits parameter - convert dict to httpx.Limits object if needed\n    if \"limits\" in processed_kwargs and isinstance(processed_kwargs[\"limits\"], dict):\n        limits_dict = processed_kwargs[\"limits\"]\n        processed_kwargs[\"limits\"] = httpx.Limits(**limits_dict)\n\n    if async_client:\n        return httpx.AsyncClient(**processed_kwargs)\n    return httpx.Client(**processed_kwargs)\n","sourceCodeStart":17,"sourceCodeEnd":48,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/utils/http_client.py#L17-L48","documentation":"TypeError raised by `init_http_client` when the http_client_kwargs parameter is truthy but not a dict. This helper builds an httpx (async) client and requires keyword arguments as a mapping so it can copy and post-process them (e.g. converting a 'limits' dict to httpx.Limits).","triggerScenarios":"Passing http_client_kwargs as a string, list, object (e.g. an httpx.Limits instance directly), or dataclass instead of a dict to components/utils that call init_http_client, e.g. http_client_kwargs=\"timeout=5\" or http_client_kwargs=httpx.Limits(...).","commonSituations":"Misreading the API and passing an httpx.Limits or httpx.Timeout object directly; passing JSON-serialized config strings; wiring a component's kwargs attribute to the wrong type.","solutions":["Pass http_client_kwargs as a dict, e.g. {'timeout': 10} or {'limits': {'max_connections': 10}}","If you already have an httpx.Limits object, pass it inside the dict: {'limits': my_limits}","Falsiness is allowed: pass None or {} to skip client creation entirely"],"exampleFix":"// before\nclient = init_http_client(http_client_kwargs=httpx.Limits(max_connections=5))\n// after\nclient = init_http_client(http_client_kwargs={\"limits\": {\"max_connections\": 5}})","handlingStrategy":"type-guard","validationCode":"def validate_client_kwargs(kwargs):\n    if kwargs is not None and not isinstance(kwargs, dict):\n        raise TypeError(\"http_client_kwargs must be a dict or None\")","typeGuard":"def is_valid_http_client_kwargs(v) -> bool:\n    return v is None or isinstance(v, dict)","tryCatchPattern":"try:\n    client = init_http_client(http_client_kwargs=kwargs)\nexcept TypeError as e:\n    log.warning(\"Bad http_client_kwargs: %s; using defaults\", e)\n    client = None","preventionTips":["Always pass a dict literal: {'timeout': 10, 'limits': {...}}","Never pass httpx.Limits/Timeout objects directly as http_client_kwargs","Load client config from JSON/dict sources, not strings or custom objects"],"tags":["haystack","httpx","typeerror","http-client"],"backgroundTag":"invalid-argument-type","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}