clockworklabs/SpacetimeDB · error · InvalidOperationException
Unsupported system type
Error message
Unsupported system type {name} What it means
For named System.* types, GetTypeInfoForNamedType only knows System.Int128/UInt128, SpacetimeDB.I128/U128/I256/U256, List<T>, IEnumerable<T> and Nullable<T>. Any other type whose original-definition name starts with 'System.' — Dictionary<K,V>, HashSet<T>, Guid, DateTime, TimeSpan, KeyValuePair, System.Numerics.* — throws InvalidOperationException, refusing to guess a BSATN layout for BCL types it has no mapping for.
Solutions
- Replace Dictionary<K,V> with List<T> of a [SpacetimeDB.Type] key/value entry struct
- Use SpacetimeDB.Identity instead of Guid for player/entity ids
- Map DateTime/DateTimeOffset/TimeSpan to long (ticks or unix microseconds)
- Replace HashSet<T> with List<T> and dedupe inside reducer logic
Example fix
// before
[SpacetimeDB.Type]
public partial struct Settings {
public Dictionary<string, int> Flags;
public Guid PlayerGuid;
public DateTime UpdatedAt;
}
// after
[SpacetimeDB.Type]
public partial struct FlagEntry { public string Key; public int Value; }
[SpacetimeDB.Type]
public partial struct Settings {
public List<FlagEntry> Flags;
public SpacetimeDB.Identity PlayerId;
public long UpdatedAtMicros;
} Defensive patterns
Strategy: validation
Validate before calling
// Compile-time: the generator rejects unmapped System.* types.
// Replacement map to apply to schema members:
// Dictionary<K,V> -> List<EntryStruct> ([SpacetimeDB.Type] { K Key; V Value; })
// HashSet<T> -> List<T>
// Guid -> SpacetimeDB.Identity (or byte[16])
// DateTime -> long micros
// TimeSpan -> long micros Try / catch
// compile-time error: nothing to catch. Replace the System.* type and rebuild.
Prevention
- Never put BCL collections or Guid/DateTime directly in schema types
- Maintain a small library of pre-approved schema DTOs and map domain models onto them
- Rebuild immediately after adding fields — the error names the offending type
When it happens
Trigger: Using Dictionary<K,V>, HashSet<T>, KeyValuePair<,>, Guid, DateTime, DateTimeOffset, TimeSpan, System.Numerics.BigInteger or any unmapped System.* type in a table column, reducer argument, or [SpacetimeDB.Type] member.
Common situations: Bringing in domain models with dictionary lookups; using Guid as a player identifier where SpacetimeDB.Identity is intended; DateTime timestamps; HashSet sets copied from server logic.
Related errors
- Unsupported special type
- Unsupported type
- Unsupported type
- Enum does not have a [SpacetimeDB.Type] attribute
- Argument must be a I128
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/871ee7ba506f358e.
Report an issue: GitHub.
Appendix: source
Thrown at crates/bindings-csharp/BSATN.Codegen/Utils.cs:181
$"Enum {type} does not have a [SpacetimeDB.Type] attribute"
);
}
return $"SpacetimeDB.BSATN.Enum<{SymbolToName(type)}>";
}
var result = type.OriginalDefinition.ToString() switch
{
// {U/I}{128/256} are not treated by C# as regular primitives, so we need to match them by type name.
"System.Int128" => "SpacetimeDB.BSATN.I128",
"System.UInt128" => "SpacetimeDB.BSATN.U128",
"SpacetimeDB.I128" => "SpacetimeDB.BSATN.I128Stdb",
"SpacetimeDB.U128" => "SpacetimeDB.BSATN.U128Stdb",
"SpacetimeDB.I256" => "SpacetimeDB.BSATN.I256",
"SpacetimeDB.U256" => "SpacetimeDB.BSATN.U256",
"System.Collections.Generic.List<T>" => $"SpacetimeDB.BSATN.List",
"System.Collections.Generic.IEnumerable<T>" => $"SpacetimeDB.BSATN.List",
// If we're here, then this is nullable *value* type like `int?`.
"System.Nullable<T>" => $"SpacetimeDB.BSATN.ValueOption",
var name when name.StartsWith("System.") => throw new InvalidOperationException(
$"Unsupported system type {name}"
),
_ => $"{SymbolToName(type)}.BSATN",
};
if (type.IsGenericType)
{
result =
$"{result}<{string.Join(", ", type.TypeArguments.Select(SymbolToName).Concat(type.TypeArguments.Select(GetTypeInfo)))}>";
}
return result;
}
}
// Polyfill for .NET methods from .NET Standard 2.1+:
private static StringBuilder AppendJoin<T>(
this StringBuilder sb,
string separator,View on GitHub (pinned to 6dee26c6ef)