When the server answers an error with a body kiota has no parse node factory for (a text/html gateway page is the usual case), the request adapter raises a plain Exception("Content type text/html does not have a factory registered to be parsed") instead of an APIError. Every except APIError in a client misses it, so the one call that fails on a 502 HTML page is the one that takes the process down instead of going through the caller's error handling.
Where it happens, on main and in 1.12.0 (unchanged since June 2025):
packages/http/httpx/kiota_http/httpx_request_adapter.py, throw_failed_responses: the try has a finally but no except. It calls _get_error_from_response, which calls get_root_parse_node to deserialize the error body.
packages/abstractions/kiota_abstractions/serialization/parse_node_factory_registry.py:48-49: get_root_parse_node raises bare Exception when no factory matches the content type.
The "failed to deserialize" wrapping later in throw_failed_responses only checks the type of the parsed object, it never sees this exception.
Repro without a network, a GraphServiceClient over an httpx MockTransport that answers 502 with text/html: https://gist.github.com/HardMax71/bc454fd1cd8285b782f603896f96980e
kiota-http 1.10.1 | msgraph-sdk 1.55.0
ESCAPED except APIError: builtins.Exception: Content type text/html does not have a factory registered to be parsed
I think two small changes would fix it: wrap _get_error_from_response in throw_failed_responses so anything raised while parsing the error body becomes APIError(status, headers) chained from the original, and make get_root_parse_node raise a typed error instead of Exception. Same ask as the last comment on microsoft/kiota#4145, which was closed as API-specific back in 2024. It is not specific to any API, any proxy or gateway can answer with HTML.
Happy to send the PR if that shape works for you, just ping me :)
When the server answers an error with a body kiota has no parse node factory for (a
text/htmlgateway page is the usual case), the request adapter raises a plainException("Content type text/html does not have a factory registered to be parsed")instead of anAPIError. Everyexcept APIErrorin a client misses it, so the one call that fails on a 502 HTML page is the one that takes the process down instead of going through the caller's error handling.Where it happens, on main and in 1.12.0 (unchanged since June 2025):
packages/http/httpx/kiota_http/httpx_request_adapter.py,throw_failed_responses: thetryhas afinallybut noexcept. It calls_get_error_from_response, which callsget_root_parse_nodeto deserialize the error body.packages/abstractions/kiota_abstractions/serialization/parse_node_factory_registry.py:48-49:get_root_parse_noderaises bareExceptionwhen no factory matches the content type.The "failed to deserialize" wrapping later in
throw_failed_responsesonly checks the type of the parsed object, it never sees this exception.Repro without a network, a GraphServiceClient over an httpx MockTransport that answers 502 with
text/html: https://gist.github.com/HardMax71/bc454fd1cd8285b782f603896f96980eI think two small changes would fix it: wrap
_get_error_from_responseinthrow_failed_responsesso anything raised while parsing the error body becomesAPIError(status, headers)chained from the original, and makeget_root_parse_noderaise a typed error instead ofException. Same ask as the last comment on microsoft/kiota#4145, which was closed as API-specific back in 2024. It is not specific to any API, any proxy or gateway can answer with HTML.Happy to send the PR if that shape works for you, just ping me :)