{"record":{"id":"46051b437fd00ef8","repo":"dotnet/orleans","slug":"unsupported-dynamodb-attribute-type-for-name","errorCode":null,"errorMessage":"Unsupported DynamoDB attribute type for '{name}'.","messagePattern":"Unsupported DynamoDB attribute type for '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/AWS/Orleans.Transactions.DynamoDB/TransactionalState/StateEntity.cs","lineNumber":149,"sourceCode":"        {\n            foreach (var (name, value) in item)\n            {\n                size += Encoding.UTF8.GetByteCount(name);\n                if (value.S is { } stringValue)\n                {\n                    size += Encoding.UTF8.GetByteCount(stringValue);\n                }\n                else if (value.N is { } numberValue)\n                {\n                    size += Encoding.UTF8.GetByteCount(numberValue);\n                }\n                else if (value.B is { } binaryValue)\n                {\n                    size += checked((int)binaryValue.Length);\n                }\n                else\n                {\n                    throw new InvalidOperationException($\"Unsupported DynamoDB attribute type for '{name}'.\");\n                }\n            }\n        }\n\n        return size;\n    }\n}\n","sourceCodeStart":131,"sourceCodeEnd":157,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/AWS/Orleans.Transactions.DynamoDB/TransactionalState/StateEntity.cs#L131-L157","documentation":"Thrown by StateEntity.GetItemSize (used to compute DynamoDB item byte size) when an AttributeValue does not match the S (string), N (number), or B (binary) scalar types. The size calculator only knows how to account for scalar attributes, so any set/list/map/bool/null attribute triggers it. It is a defensive guard indicating an attribute shape the provider does not produce itself.","triggerScenarios":"Produced when ToStorageFormat() of a KeyEntity/StateEntity (or any item passed to GetItemSize) contains an AttributeValue using SS, NS, BS, L, M, BOOL, or NULL. Triggered by code that builds DynamoDB items with non-scalar attributes and feeds them through GetItemSize/ValidateItemSize (e.g., a fork that serializes collections as list/map attributes).","commonSituations":"Custom fork or extension storing set/list/map/bool attributes on the transactional state rows; a migration from another provider that wrote richer attribute types; test code hand-crafting items.","solutions":["Ensure all attributes on KeyEntity/StateEntity items are scalar (S/N/B) — the provider serializes complex state as a single binary B attribute via the configured serializer.","If you must store non-scalar attributes, extend GetItemSize to account for their byte sizes (per the DynamoDB item-size rules).","Re-check that you are using the provider's own ToStorageFormat() rather than constructing AttributeValue dictionaries by hand."],"exampleFix":"// before: hand-built item with a list attribute\nitem[\"tags\"] = new AttributeValue { L = new List<AttributeValue> { /*...*/ } };\nvar size = StateEntity.GetItemSize(item); // throws\n\n// after: keep state as a single serialized binary scalar\nitem[\"state\"] = new AttributeValue { B = new MemoryStream(serializer.Serialize(myState).ToArray()) };\nvar size = StateEntity.GetItemSize(item);","handlingStrategy":"type-guard","validationCode":"// Confirm every attribute on items you feed to GetItemSize is scalar\nstatic bool AllScalar(Dictionary<string,AttributeValue> item) =>\n    item.Values.All(v => v.S is not null || v.N is not null || v.B is not null);","typeGuard":"static bool IsSupportedAttribute(AttributeValue v) => v.S is not null || v.N is not null || v.B is not null;","tryCatchPattern":"try { var size = StateEntity.GetItemSize(item); }\ncatch (InvalidOperationException ix) when (ix.Message.Contains(\"Unsupported DynamoDB attribute type\"))\n{\n    _logger.LogCritical(\"Item contains a non-scalar (set/list/map/bool/null) attribute; serialize complex state as binary\");\n    throw;\n}","preventionTips":["Always serialize complex state into a single binary (B) attribute via the configured serializer.","Never hand-build items with L/M/SS/NS/BS/BOOL/NULL if they will pass through GetItemSize.","If you extend the schema with non-scalar attributes, update GetItemSize to compute their sizes.","Prefer the provider's ToStorageFormat() over manual AttributeValue construction."],"tags":["dynamodb","attribute-type","item-size","programming-error"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}