iot describe_thing returns 500 InternalError after update_thing sets thingTypeName #50
yaxi-lei-simplisafe
started this conversation in
Bugs
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Calling update_thing with a thingTypeName (either the same value that create_thing set, or a new value) leaves the internal Thing record in a state where any subsequent describe_thing, list_things, or search_index call fails to serialize its response and returns 500 InternalError.
Minimal reproducer (AWS CLI against localstack-pro)
Expected: describe-thing returns {"thingName":"t1","thingTypeName":"thingType","attributes":{...}} — matches real AWS behavior (verified against a real AWS account, same sequence works).
Actual: describe-thing returns HTTP 500 with:
An error occurred (InternalError) when calling the DescribeThing operation:
exception while calling iot.DescribeThing: An unknown error occurred when trying to serialize the response.
Server-side traceback:
File ".../localstack/aws/protocol/serializer.py", line 1290, in _serialize_body_params
return json.dumps(body)
TypeError: Object of type FakeThingType is not JSON serializable
Not affected
Only the combination "update_thing passes thingTypeName" corrupts subsequent reads.
Environment tested
Isolation: pure moto is NOT the culprit
Running the exact same sequence under pure moto (via @mock_aws, no localstack involved) succeeds:
moto/iot/models.py:FakeThing.to_dict() correctly maps self.thing_type.thing_type_name to the string "thingType". moto.iot.responses.IoTResponse.describe_thing does json.dumps(thing.to_dict(...)) and returns the correct payload. moto is fine.
Root cause (revised): LocalStack Pro's own IoT provider
Provider registration in localstack/pro/core/providers.py:
MotoFallbackDispatcher routes each operation to IotProvider if implemented, else falls back to moto. Since pure moto works but the Pro image doesn't, IotProvider (in localstack/pro/core/services/iot/provider.py — shipped as an encrypted .enc file in the image) is overriding describe_thing / update_thing and bypassing moto's to_dict(). The override appears to hand the raw moto.iot.models.FakeThing (or a proxy of it) to the AWS-protocol serializer, which picks up the thing_type attribute — a FakeThingType object — into the response body dict before json.dumps. Either the Pro provider should call to_dict() on the FakeThing before returning, or it should project thing_type → thing_type.thing_type_name (string) itself.
Impact
Any integration test that exercises the real AWS pattern "create a thing, then UpdateThing to associate/change its type, then read it back" is forced into a workaround (update_thing(removeThingType=True) before reads) because LocalStack Pro's read APIs 500. This is a common pattern for healing or migrating thing types in production code.
All reactions