<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic [BUG] RADKit 1.9.5 — fail with FastAPI &amp;gt; 0.131.0 in RADKit Discussions</title>
    <link>https://community.cisco.com/t5/radkit-discussions/bug-radkit-1-9-5-fail-with-fastapi-gt-0-131-0/m-p/5373485#M226</link>
    <description>&lt;DIV&gt;&lt;SPAN&gt;# [BUG] RADKit 1.9.5 — `create_devices` / `create_device` fail with FastAPI &amp;gt; 0.131.0&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;**Category:**&lt;/SPAN&gt;&lt;SPAN&gt; RADKit / Python SDK / Control API&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;**RADKit version:**&lt;/SPAN&gt;&lt;SPAN&gt; 1.9.5&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;**Affected methods:**&lt;/SPAN&gt; &lt;SPAN&gt;`ControlAPI.create_devices()`&lt;/SPAN&gt;&lt;SPAN&gt;, &lt;/SPAN&gt;&lt;SPAN&gt;`ControlAPI.create_device()`&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;**Root cause:**&lt;/SPAN&gt;&lt;SPAN&gt; Incompatibility with FastAPI &amp;gt;= 0.132.0&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;---&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;## Summary&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;When using the RADKit Python SDK (&lt;/SPAN&gt;&lt;SPAN&gt;`cisco_radkit_service==1.9.5`&lt;/SPAN&gt;&lt;SPAN&gt;) in an environment where FastAPI has been upgraded beyond version &lt;/SPAN&gt;&lt;SPAN&gt;`0.131.0`&lt;/SPAN&gt;&lt;SPAN&gt;, all write operations through &lt;/SPAN&gt;&lt;SPAN&gt;`ControlAPI`&lt;/SPAN&gt;&lt;SPAN&gt; fail silently with a Pydantic body-validation error. Read operations (&lt;/SPAN&gt;&lt;SPAN&gt;`list_devices`&lt;/SPAN&gt;&lt;SPAN&gt;, &lt;/SPAN&gt;&lt;SPAN&gt;`get_service_status`&lt;/SPAN&gt;&lt;SPAN&gt;) are unaffected.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;This post was written with the help of Claude (Anthropic) who assisted in debugging and isolating the root cause.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;---&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;## Symptoms&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;Calling &lt;/SPAN&gt;&lt;SPAN&gt;`service.control_api.create_devices(devices)`&lt;/SPAN&gt;&lt;SPAN&gt; with a valid &lt;/SPAN&gt;&lt;SPAN&gt;`list[NewDevice]`&lt;/SPAN&gt;&lt;SPAN&gt; returns an error result instead of raising a Python exception:&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;Input Validation Error&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;root=Error(&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; success=False,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; message='Input should be a valid list',&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; detail=[{'type': 'list_type', 'msg': 'Input should be a valid list', 'loc': 'body'}]&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;)&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;Similarly, &lt;/SPAN&gt;&lt;SPAN&gt;`create_device(device)`&lt;/SPAN&gt;&lt;SPAN&gt; (singular) returns:&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;root=Error(&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; success=False,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; message='Input should be a valid dictionary or object to extract fields from',&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; detail=[{'type': 'model_attributes_type', 'msg': '...', 'loc': 'body'}]&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;)&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;The Python call does &lt;/SPAN&gt;&lt;SPAN&gt;**not**&lt;/SPAN&gt;&lt;SPAN&gt; raise an exception — the error is embedded in the return value, making it easy to miss.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;---&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;## Reproduction&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;### Environment that works&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;cisco_radkit_service==1.9.5&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;fastapi==0.131.0&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;starlette==0.52.1&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;pydantic==2.11.7&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;### Environment that fails&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;cisco_radkit_service==1.9.5&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;fastapi==0.134.0 &amp;nbsp; ← any version &amp;gt; 0.131.0 is affected&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;starlette==0.52.1&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;pydantic==2.11.7&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;All versions of FastAPI strictly greater than &lt;/SPAN&gt;&lt;SPAN&gt;`0.131.0`&lt;/SPAN&gt;&lt;SPAN&gt; up to at least &lt;/SPAN&gt;&lt;SPAN&gt;`0.134.0`&lt;/SPAN&gt;&lt;SPAN&gt; are affected (tested exhaustively).&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;### Minimal reproduction script&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```python&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;from&lt;/SPAN&gt;&lt;SPAN&gt; radkit_client.sync &lt;/SPAN&gt;&lt;SPAN&gt;import&lt;/SPAN&gt;&lt;SPAN&gt; Client&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;from&lt;/SPAN&gt;&lt;SPAN&gt; radkit_common.types &lt;/SPAN&gt;&lt;SPAN&gt;import&lt;/SPAN&gt;&lt;SPAN&gt; DeviceType&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;from&lt;/SPAN&gt;&lt;SPAN&gt; radkit_service.webserver.models.devices &lt;/SPAN&gt;&lt;SPAN&gt;import&lt;/SPAN&gt;&lt;SPAN&gt; NewDevice, NewTerminal&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;terminal = NewTerminal(&lt;/SPAN&gt;&lt;SPAN&gt;username&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;"admin"&lt;/SPAN&gt;&lt;SPAN&gt;, &lt;/SPAN&gt;&lt;SPAN&gt;password&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;"Cisco123"&lt;/SPAN&gt;&lt;SPAN&gt;)&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;device = NewDevice(&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;name&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;"test-device"&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;host&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;"test-device.example.com"&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;deviceType&lt;/SPAN&gt;&lt;SPAN&gt;=DeviceType.GENERIC,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;terminal&lt;/SPAN&gt;&lt;SPAN&gt;=terminal,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;enabled&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;True&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;)&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;with&lt;/SPAN&gt;&lt;SPAN&gt; Client.create() &lt;/SPAN&gt;&lt;SPAN&gt;as&lt;/SPAN&gt;&lt;SPAN&gt; client:&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; service = client.create_service(&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;radkit_directory&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;"local_radkit"&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;autobootstrap&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;True&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;superadmin_password&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;"&amp;lt;your_password&amp;gt;"&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; )&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; result = service.control_api.create_devices([device])&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;print&lt;/SPAN&gt;&lt;SPAN&gt;(result)&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;# With fastapi==0.131.0 → BulkResult with success_count=1&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;# With fastapi&amp;gt;=0.132.0 → Error(success=False, message='Input should be a valid list')&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;---&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;## Root Cause Analysis&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;`service.control_api`&lt;/SPAN&gt;&lt;SPAN&gt; is a synchronous proxy object (&lt;/SPAN&gt;&lt;SPAN&gt;`radkit_service.control_api.ControlAPI`&lt;/SPAN&gt;&lt;SPAN&gt;) that serializes Python calls into HTTP requests directed at RADKit's internal FastAPI webserver. The device objects (&lt;/SPAN&gt;&lt;SPAN&gt;`NewDevice`&lt;/SPAN&gt;&lt;SPAN&gt;, &lt;/SPAN&gt;&lt;SPAN&gt;`NewTerminal`&lt;/SPAN&gt;&lt;SPAN&gt;) use Pydantic &lt;/SPAN&gt;&lt;SPAN&gt;`CustomSecretStr`&lt;/SPAN&gt;&lt;SPAN&gt; fields for sensitive values (passwords, keys).&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;Between FastAPI &lt;/SPAN&gt;&lt;SPAN&gt;`0.131.0`&lt;/SPAN&gt;&lt;SPAN&gt; and &lt;/SPAN&gt;&lt;SPAN&gt;`0.132.0`&lt;/SPAN&gt;&lt;SPAN&gt;, the framework changed how it validates and deserializes request bodies containing Pydantic models with custom secret types. The internal HTTP layer can no longer correctly serialize &lt;/SPAN&gt;&lt;SPAN&gt;`list[NewDevice]`&lt;/SPAN&gt;&lt;SPAN&gt; into a valid JSON body, causing the FastAPI endpoint to reject it with a body-validation error before the actual logic is reached.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;The error originates server-side inside RADKit's own webserver process, which is why no Python exception is raised — the call completes successfully from the SDK's perspective, but carries a failure payload.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;**Key evidence:**&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;-&lt;/SPAN&gt; &lt;SPAN&gt;`type(service.control_api)`&lt;/SPAN&gt;&lt;SPAN&gt; → &lt;/SPAN&gt;&lt;SPAN&gt;`&amp;lt;class 'radkit_service.control_api.ControlAPI'&amp;gt;`&lt;/SPAN&gt;&lt;SPAN&gt; ✓ correct type&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;-&lt;/SPAN&gt; &lt;SPAN&gt;`inspect.signature(service.control_api.create_devices)`&lt;/SPAN&gt;&lt;SPAN&gt; → &lt;/SPAN&gt;&lt;SPAN&gt;`(devices: Sequence[NewDevice]) -&amp;gt; BulkResult[StoredDeviceWithMetadata]`&lt;/SPAN&gt;&lt;SPAN&gt; ✓ correct signature&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;-&lt;/SPAN&gt;&lt;SPAN&gt; Passing &lt;/SPAN&gt;&lt;SPAN&gt;`list[NewDevice]`&lt;/SPAN&gt;&lt;SPAN&gt; → body validation error (FastAPI rejects it)&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;-&lt;/SPAN&gt;&lt;SPAN&gt; Passing &lt;/SPAN&gt;&lt;SPAN&gt;`list[dict]`&lt;/SPAN&gt;&lt;SPAN&gt; (via &lt;/SPAN&gt;&lt;SPAN&gt;`model_dump()`&lt;/SPAN&gt;&lt;SPAN&gt;) → same error&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;-&lt;/SPAN&gt;&lt;SPAN&gt; Downgrading to &lt;/SPAN&gt;&lt;SPAN&gt;`fastapi==0.131.0`&lt;/SPAN&gt;&lt;SPAN&gt; → works immediately, no code changes needed&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;---&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;## Workaround&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;Pin FastAPI to &lt;/SPAN&gt;&lt;SPAN&gt;`0.131.0`&lt;/SPAN&gt;&lt;SPAN&gt; until a fix is released:&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;```bash&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;pip&lt;/SPAN&gt; &lt;SPAN&gt;install&lt;/SPAN&gt; &lt;SPAN&gt;"fastapi==0.131.0"&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;Or in &lt;/SPAN&gt;&lt;SPAN&gt;`pyproject.toml`&lt;/SPAN&gt;&lt;SPAN&gt; / &lt;/SPAN&gt;&lt;SPAN&gt;`requirements.txt`&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;fastapi==0.131.0&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;---&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;## Request&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;Please pin or constrain the FastAPI version in RADKit's dependencies so that &lt;/SPAN&gt;&lt;SPAN&gt;`pip install cisco_radkit_service`&lt;/SPAN&gt;&lt;SPAN&gt; does not silently pull in an incompatible version. A constraint such as &lt;/SPAN&gt;&lt;SPAN&gt;`fastapi&amp;gt;=0.100.0,&amp;lt;=0.131.0`&lt;/SPAN&gt;&lt;SPAN&gt; (or whatever upper bound is validated) would prevent this issue for new installs.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;Ideally, the incompatibility with FastAPI &amp;gt;= 0.132.0 should be investigated and fixed so that RADKit works with current releases of the framework.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;---&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;*Tested on: Windows 11, Python 3.13, RADKit 1.9.5, integrated (bootstrap) service mode.*&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;*Debugging assisted by Claude (Anthropic).*&lt;/SPAN&gt;&lt;/DIV&gt;</description>
    <pubDate>Sat, 28 Feb 2026 12:09:51 GMT</pubDate>
    <dc:creator>MarcoZaurus</dc:creator>
    <dc:date>2026-02-28T12:09:51Z</dc:date>
    <item>
      <title>[BUG] RADKit 1.9.5 — fail with FastAPI &gt; 0.131.0</title>
      <link>https://community.cisco.com/t5/radkit-discussions/bug-radkit-1-9-5-fail-with-fastapi-gt-0-131-0/m-p/5373485#M226</link>
      <description>&lt;DIV&gt;&lt;SPAN&gt;# [BUG] RADKit 1.9.5 — `create_devices` / `create_device` fail with FastAPI &amp;gt; 0.131.0&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;**Category:**&lt;/SPAN&gt;&lt;SPAN&gt; RADKit / Python SDK / Control API&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;**RADKit version:**&lt;/SPAN&gt;&lt;SPAN&gt; 1.9.5&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;**Affected methods:**&lt;/SPAN&gt; &lt;SPAN&gt;`ControlAPI.create_devices()`&lt;/SPAN&gt;&lt;SPAN&gt;, &lt;/SPAN&gt;&lt;SPAN&gt;`ControlAPI.create_device()`&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;**Root cause:**&lt;/SPAN&gt;&lt;SPAN&gt; Incompatibility with FastAPI &amp;gt;= 0.132.0&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;---&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;## Summary&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;When using the RADKit Python SDK (&lt;/SPAN&gt;&lt;SPAN&gt;`cisco_radkit_service==1.9.5`&lt;/SPAN&gt;&lt;SPAN&gt;) in an environment where FastAPI has been upgraded beyond version &lt;/SPAN&gt;&lt;SPAN&gt;`0.131.0`&lt;/SPAN&gt;&lt;SPAN&gt;, all write operations through &lt;/SPAN&gt;&lt;SPAN&gt;`ControlAPI`&lt;/SPAN&gt;&lt;SPAN&gt; fail silently with a Pydantic body-validation error. Read operations (&lt;/SPAN&gt;&lt;SPAN&gt;`list_devices`&lt;/SPAN&gt;&lt;SPAN&gt;, &lt;/SPAN&gt;&lt;SPAN&gt;`get_service_status`&lt;/SPAN&gt;&lt;SPAN&gt;) are unaffected.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;This post was written with the help of Claude (Anthropic) who assisted in debugging and isolating the root cause.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;---&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;## Symptoms&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;Calling &lt;/SPAN&gt;&lt;SPAN&gt;`service.control_api.create_devices(devices)`&lt;/SPAN&gt;&lt;SPAN&gt; with a valid &lt;/SPAN&gt;&lt;SPAN&gt;`list[NewDevice]`&lt;/SPAN&gt;&lt;SPAN&gt; returns an error result instead of raising a Python exception:&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;Input Validation Error&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;root=Error(&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; success=False,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; message='Input should be a valid list',&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; detail=[{'type': 'list_type', 'msg': 'Input should be a valid list', 'loc': 'body'}]&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;)&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;Similarly, &lt;/SPAN&gt;&lt;SPAN&gt;`create_device(device)`&lt;/SPAN&gt;&lt;SPAN&gt; (singular) returns:&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;root=Error(&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; success=False,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; message='Input should be a valid dictionary or object to extract fields from',&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; detail=[{'type': 'model_attributes_type', 'msg': '...', 'loc': 'body'}]&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;)&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;The Python call does &lt;/SPAN&gt;&lt;SPAN&gt;**not**&lt;/SPAN&gt;&lt;SPAN&gt; raise an exception — the error is embedded in the return value, making it easy to miss.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;---&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;## Reproduction&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;### Environment that works&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;cisco_radkit_service==1.9.5&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;fastapi==0.131.0&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;starlette==0.52.1&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;pydantic==2.11.7&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;### Environment that fails&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;cisco_radkit_service==1.9.5&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;fastapi==0.134.0 &amp;nbsp; ← any version &amp;gt; 0.131.0 is affected&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;starlette==0.52.1&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;pydantic==2.11.7&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;All versions of FastAPI strictly greater than &lt;/SPAN&gt;&lt;SPAN&gt;`0.131.0`&lt;/SPAN&gt;&lt;SPAN&gt; up to at least &lt;/SPAN&gt;&lt;SPAN&gt;`0.134.0`&lt;/SPAN&gt;&lt;SPAN&gt; are affected (tested exhaustively).&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;### Minimal reproduction script&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```python&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;from&lt;/SPAN&gt;&lt;SPAN&gt; radkit_client.sync &lt;/SPAN&gt;&lt;SPAN&gt;import&lt;/SPAN&gt;&lt;SPAN&gt; Client&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;from&lt;/SPAN&gt;&lt;SPAN&gt; radkit_common.types &lt;/SPAN&gt;&lt;SPAN&gt;import&lt;/SPAN&gt;&lt;SPAN&gt; DeviceType&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;from&lt;/SPAN&gt;&lt;SPAN&gt; radkit_service.webserver.models.devices &lt;/SPAN&gt;&lt;SPAN&gt;import&lt;/SPAN&gt;&lt;SPAN&gt; NewDevice, NewTerminal&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;terminal = NewTerminal(&lt;/SPAN&gt;&lt;SPAN&gt;username&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;"admin"&lt;/SPAN&gt;&lt;SPAN&gt;, &lt;/SPAN&gt;&lt;SPAN&gt;password&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;"Cisco123"&lt;/SPAN&gt;&lt;SPAN&gt;)&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;device = NewDevice(&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;name&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;"test-device"&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;host&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;"test-device.example.com"&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;deviceType&lt;/SPAN&gt;&lt;SPAN&gt;=DeviceType.GENERIC,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;terminal&lt;/SPAN&gt;&lt;SPAN&gt;=terminal,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;enabled&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;True&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;)&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;with&lt;/SPAN&gt;&lt;SPAN&gt; Client.create() &lt;/SPAN&gt;&lt;SPAN&gt;as&lt;/SPAN&gt;&lt;SPAN&gt; client:&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; service = client.create_service(&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;radkit_directory&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;"local_radkit"&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;autobootstrap&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;True&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;superadmin_password&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;"&amp;lt;your_password&amp;gt;"&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; )&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; result = service.control_api.create_devices([device])&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;print&lt;/SPAN&gt;&lt;SPAN&gt;(result)&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;# With fastapi==0.131.0 → BulkResult with success_count=1&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;# With fastapi&amp;gt;=0.132.0 → Error(success=False, message='Input should be a valid list')&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;---&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;## Root Cause Analysis&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;`service.control_api`&lt;/SPAN&gt;&lt;SPAN&gt; is a synchronous proxy object (&lt;/SPAN&gt;&lt;SPAN&gt;`radkit_service.control_api.ControlAPI`&lt;/SPAN&gt;&lt;SPAN&gt;) that serializes Python calls into HTTP requests directed at RADKit's internal FastAPI webserver. The device objects (&lt;/SPAN&gt;&lt;SPAN&gt;`NewDevice`&lt;/SPAN&gt;&lt;SPAN&gt;, &lt;/SPAN&gt;&lt;SPAN&gt;`NewTerminal`&lt;/SPAN&gt;&lt;SPAN&gt;) use Pydantic &lt;/SPAN&gt;&lt;SPAN&gt;`CustomSecretStr`&lt;/SPAN&gt;&lt;SPAN&gt; fields for sensitive values (passwords, keys).&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;Between FastAPI &lt;/SPAN&gt;&lt;SPAN&gt;`0.131.0`&lt;/SPAN&gt;&lt;SPAN&gt; and &lt;/SPAN&gt;&lt;SPAN&gt;`0.132.0`&lt;/SPAN&gt;&lt;SPAN&gt;, the framework changed how it validates and deserializes request bodies containing Pydantic models with custom secret types. The internal HTTP layer can no longer correctly serialize &lt;/SPAN&gt;&lt;SPAN&gt;`list[NewDevice]`&lt;/SPAN&gt;&lt;SPAN&gt; into a valid JSON body, causing the FastAPI endpoint to reject it with a body-validation error before the actual logic is reached.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;The error originates server-side inside RADKit's own webserver process, which is why no Python exception is raised — the call completes successfully from the SDK's perspective, but carries a failure payload.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;**Key evidence:**&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;-&lt;/SPAN&gt; &lt;SPAN&gt;`type(service.control_api)`&lt;/SPAN&gt;&lt;SPAN&gt; → &lt;/SPAN&gt;&lt;SPAN&gt;`&amp;lt;class 'radkit_service.control_api.ControlAPI'&amp;gt;`&lt;/SPAN&gt;&lt;SPAN&gt; ✓ correct type&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;-&lt;/SPAN&gt; &lt;SPAN&gt;`inspect.signature(service.control_api.create_devices)`&lt;/SPAN&gt;&lt;SPAN&gt; → &lt;/SPAN&gt;&lt;SPAN&gt;`(devices: Sequence[NewDevice]) -&amp;gt; BulkResult[StoredDeviceWithMetadata]`&lt;/SPAN&gt;&lt;SPAN&gt; ✓ correct signature&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;-&lt;/SPAN&gt;&lt;SPAN&gt; Passing &lt;/SPAN&gt;&lt;SPAN&gt;`list[NewDevice]`&lt;/SPAN&gt;&lt;SPAN&gt; → body validation error (FastAPI rejects it)&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;-&lt;/SPAN&gt;&lt;SPAN&gt; Passing &lt;/SPAN&gt;&lt;SPAN&gt;`list[dict]`&lt;/SPAN&gt;&lt;SPAN&gt; (via &lt;/SPAN&gt;&lt;SPAN&gt;`model_dump()`&lt;/SPAN&gt;&lt;SPAN&gt;) → same error&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;-&lt;/SPAN&gt;&lt;SPAN&gt; Downgrading to &lt;/SPAN&gt;&lt;SPAN&gt;`fastapi==0.131.0`&lt;/SPAN&gt;&lt;SPAN&gt; → works immediately, no code changes needed&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;---&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;## Workaround&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;Pin FastAPI to &lt;/SPAN&gt;&lt;SPAN&gt;`0.131.0`&lt;/SPAN&gt;&lt;SPAN&gt; until a fix is released:&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;```bash&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;pip&lt;/SPAN&gt; &lt;SPAN&gt;install&lt;/SPAN&gt; &lt;SPAN&gt;"fastapi==0.131.0"&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;Or in &lt;/SPAN&gt;&lt;SPAN&gt;`pyproject.toml`&lt;/SPAN&gt;&lt;SPAN&gt; / &lt;/SPAN&gt;&lt;SPAN&gt;`requirements.txt`&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;fastapi==0.131.0&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;```&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;---&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;## Request&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;Please pin or constrain the FastAPI version in RADKit's dependencies so that &lt;/SPAN&gt;&lt;SPAN&gt;`pip install cisco_radkit_service`&lt;/SPAN&gt;&lt;SPAN&gt; does not silently pull in an incompatible version. A constraint such as &lt;/SPAN&gt;&lt;SPAN&gt;`fastapi&amp;gt;=0.100.0,&amp;lt;=0.131.0`&lt;/SPAN&gt;&lt;SPAN&gt; (or whatever upper bound is validated) would prevent this issue for new installs.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;Ideally, the incompatibility with FastAPI &amp;gt;= 0.132.0 should be investigated and fixed so that RADKit works with current releases of the framework.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;---&lt;/SPAN&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;SPAN&gt;*Tested on: Windows 11, Python 3.13, RADKit 1.9.5, integrated (bootstrap) service mode.*&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;*Debugging assisted by Claude (Anthropic).*&lt;/SPAN&gt;&lt;/DIV&gt;</description>
      <pubDate>Sat, 28 Feb 2026 12:09:51 GMT</pubDate>
      <guid>https://community.cisco.com/t5/radkit-discussions/bug-radkit-1-9-5-fail-with-fastapi-gt-0-131-0/m-p/5373485#M226</guid>
      <dc:creator>MarcoZaurus</dc:creator>
      <dc:date>2026-02-28T12:09:51Z</dc:date>
    </item>
  </channel>
</rss>

