dotnet/orleans · error · InvalidOperationException
Inform grain id in format {id},{additionalKey}
Error message
Inform grain id in format {id},{additionalKey} What it means
InvalidOperationException from GrainStateHelper.GetGrainId when the implementation type implements IGrainWithIntegerCompoundKey but the id does not split into exactly two comma-separated parts. Requires exactly 'integer,additionalKey'. Note the message text differs slightly from error 355 (no stray backticks) but the contract is identical for integer compound keys.
Source
Thrown at src/Dashboard/Orleans.Dashboard/Implementation/Helpers/GrainStateHelper.cs:30
{
object? grainId = null;
string keyExtension = "";
var splitedGrainId = id.Split(",");
try
{
if (implementationType.IsAssignableTo(typeof(IGrainWithGuidCompoundKey)))
{
if (splitedGrainId.Length != 2)
throw new InvalidOperationException("Inform grain id in format `{ id},{additionalKey}`");
grainId = Guid.Parse(splitedGrainId.First());
keyExtension = splitedGrainId.Last();
}
else if (implementationType.IsAssignableTo(typeof(IGrainWithIntegerCompoundKey)))
{
if (splitedGrainId.Length != 2)
throw new InvalidOperationException("Inform grain id in format {id},{additionalKey}");
grainId = Convert.ToInt64(splitedGrainId.First());
keyExtension = splitedGrainId.Last();
}
else if (implementationType.IsAssignableTo(typeof(IGrainWithIntegerKey)))
{
grainId = Convert.ToInt64(id);
}
else if (implementationType.IsAssignableTo(typeof(IGrainWithGuidKey)))
{
grainId = Guid.Parse(id);
}
else if (implementationType.IsAssignableTo(typeof(IGrainWithStringKey)))
{
grainId = id;
}
}
catch (Exception ex)View on GitHub (pinned to fca799fa70)
Solutions
- Pass ids for integer-compound grains as 'long,additionalKey' with exactly one comma.
- Validate format and that the first part is a 64-bit integer before calling.
- Confirm the grain interface marker type matches the key shape you expect.
Example fix
// before
var (gid, ext) = GrainStateHelper.GetGrainId(rawId, typeof(MyIntCompoundGrain));
// after
var parts = rawId.Split(',');
if (parts.Length != 2 || !long.TryParse(parts[0], out _))
return BadRequest("id must be 'long,additionalKey'");
var (gid, ext) = GrainStateHelper.GetGrainId(rawId, typeof(MyIntCompoundGrain)); Defensive patterns
Strategy: validation
Validate before calling
var parts = id.Split(',');
if (parts.Length != 2 || !long.TryParse(parts[0], out _))
return BadRequest("id must be 'long,additionalKey'");
var (gid, ext) = GrainStateHelper.GetGrainId(id, type); Type guard
static bool IsValidIntCompoundId(string id) =>
id.Split(',') is { Length: 2 } p && long.TryParse(p[0], out _); Try / catch
try { var (gid, ext) = GrainStateHelper.GetGrainId(id, type); }
catch (InvalidOperationException ex) when (ex.Message.Contains("grain id in format"))
{ return BadRequest("compound integer id malformed"); } Prevention
- Validate the 'long,key' format before requesting grain state
- Ensure frontend sends both segments
- Match interface markers to the key type
When it happens
Trigger: Dashboard requests grain state for a grain whose implementation type is IGrainWithIntegerCompoundKey, and the id string does not contain exactly one comma (splitedGrainId.Length != 2). Convert.ToInt64 on a non-numeric first part would also throw and be wrapped by error 357.
Common situations: Malformed id from the dashboard UI, a grain registered with an integer compound key but invoked with only the long portion, or frontend code that omits the additional key.
Related errors
- Inform grain id in format `{ id},{additionalKey}`
- Error when trying to convert grain Id
- The frontend cant support more than 6 silos
- Unknown Playground:Storage:Provider value '{storageProvider}
- count
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/64f958e495df8034.
Report an issue: GitHub.