dotnet/orleans · error · InvalidOperationException
Unsupported DynamoDB attribute type for '{name}'.
Error message
Unsupported DynamoDB attribute type for '{name}'. What it means
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.
Source
Thrown at src/AWS/Orleans.Transactions.DynamoDB/TransactionalState/StateEntity.cs:149
{
foreach (var (name, value) in item)
{
size += Encoding.UTF8.GetByteCount(name);
if (value.S is { } stringValue)
{
size += Encoding.UTF8.GetByteCount(stringValue);
}
else if (value.N is { } numberValue)
{
size += Encoding.UTF8.GetByteCount(numberValue);
}
else if (value.B is { } binaryValue)
{
size += checked((int)binaryValue.Length);
}
else
{
throw new InvalidOperationException($"Unsupported DynamoDB attribute type for '{name}'.");
}
}
}
return size;
}
}
View on GitHub (pinned to fca799fa70)
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.
Example fix
// before: hand-built item with a list attribute
item["tags"] = new AttributeValue { L = new List<AttributeValue> { /*...*/ } };
var size = StateEntity.GetItemSize(item); // throws
// after: keep state as a single serialized binary scalar
item["state"] = new AttributeValue { B = new MemoryStream(serializer.Serialize(myState).ToArray()) };
var size = StateEntity.GetItemSize(item); Defensive patterns
Strategy: type-guard
Validate before calling
// Confirm every attribute on items you feed to GetItemSize is scalar
static bool AllScalar(Dictionary<string,AttributeValue> item) =>
item.Values.All(v => v.S is not null || v.N is not null || v.B is not null); Type guard
static bool IsSupportedAttribute(AttributeValue v) => v.S is not null || v.N is not null || v.B is not null;
Try / catch
try { var size = StateEntity.GetItemSize(item); }
catch (InvalidOperationException ix) when (ix.Message.Contains("Unsupported DynamoDB attribute type"))
{
_logger.LogCritical("Item contains a non-scalar (set/list/map/bool/null) attribute; serialize complex state as binary");
throw;
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- Only DynamoDB put and delete operations are supported.
- Configuration for DynamoDBGrainStorage {name} is invalid. Ta
- Configuration for DynamoDBGrainStorage {name} is invalid. Re
- Configuration for DynamoDBGrainStorage {name} is invalid. Wr
- Data too large to write to DynamoDB table. Size={dataSize} M
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/46051b437fd00ef8.
Report an issue: GitHub.