stride3d/stride · error · InvalidOperationException
ResourceGroup has no ResourceGroupSDSL name decoration
Error message
ResourceGroup {groupId} has no ResourceGroupSDSL name decoration What it means
StreamAnalyzer.Analyze groups resources by their ResourceGroup id. Each group id must have an OpName/ResourceGroupSDSL name decoration recorded in groupNames; when a target references a group id with no recorded name, the analyzer cannot construct the ResourceGroup and throws InvalidOperationException.
Solutions
- Ensure every ResourceGroup id gets a ResourceGroupSDSL name decoration before Analyze runs
- Check pass ordering: the naming pass must execute before StreamAnalyzer.Analyze
- Verify groupNames is populated from the right decoration type/key for the groupId
- Inspect which groupId is missing a name (printed in the message) and find the transformation that created it
Example fix
// before
group MyResources : ResourceGroupSDSL { } // name decoration missing for the id used
// after
group MyResources : ResourceGroupSDSL { Texture2D tex; }; // ensure group is declared and decorated so groupNames contains its id Defensive patterns
Strategy: validation
Validate before calling
foreach (var groupId in groupIdByTarget.Values)
if (!groupNames.ContainsKey(groupId)) throw new InvalidOperationException($"ResourceGroup {groupId} is missing a ResourceGroupSDSL name decoration"); Try / catch
try { analyzer.Analyze(module); } catch (InvalidOperationException ex) { logger.LogError(ex, "Undecorated resource group"); throw new ShaderCompilationException("Resource group name decoration missing", ex); } Prevention
- Always declare resource groups with explicit names in SDSL
- Run decoration-collecting passes before StreamAnalyzer
- Avoid transformations that strip OpName from group instructions
When it happens
Trigger: A descriptor/OpDecorate pipeline associates a resource with a ResourceGroup id for which no ResourceGroupSDSL name decoration was emitted — e.g. decorations stripped, order of analysis passes wrong, or a group created implicitly by a transformation without naming it.
Common situations: Upstream passes renaming/removing OpName decorations before StreamAnalyzer runs; shader code or transformations creating descriptor sets without explicit group names; mismatched decoration keys (groupId vs target).
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- 64bit integers
- Can't add type
- Can't write value on input or output struct
- Could not load shader
- Couldn't figure out element type for binary operation…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/55bca9ff74223dfd.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs:162
groupIdByTarget.TryAdd(resourceGroupIdDecorate.Target, m.To<DecorationParams.ResourceGroupIdSDSL>().ResourceGroup);
}
// Resolve group ID → name (first target with both a group ID and a ResourceGroupSDSL name wins)
Dictionary<int, string> groupNames = new();
foreach (var (target, groupId) in groupIdByTarget)
{
if (!groupNames.ContainsKey(groupId) && resourceGroupNamesByTarget.TryGetValue(target, out var name))
groupNames.Add(groupId, name);
}
// Build ResourceGroups and assign resources/cbuffers
Dictionary<int, ResourceGroup> resourceGroups = new();
foreach (var (target, groupId) in groupIdByTarget)
{
if (!resourceGroups.TryGetValue(groupId, out var resourceGroup))
{
if (!groupNames.TryGetValue(groupId, out var name))
throw new InvalidOperationException($"ResourceGroup {groupId} has no ResourceGroupSDSL name decoration");
resourceGroups.Add(groupId, resourceGroup = new(name));
}
if (resources.TryGetValue(target, out var resourceInfo))
{
resourceGroup.Resources.Add(resourceInfo);
resourceInfo.ResourceGroup = resourceGroup;
}
else if (cbuffers.TryGetValue(target, out var cbufferInfo))
{
cbufferInfo.ResourceGroup = resourceGroup;
}
// Apply LogicalGroup if present
if (logicalGroupNamesByTarget.TryGetValue(target, out var logicalGroup))
{
resourceGroup.LogicalGroup ??= logicalGroup;
if (cbuffers.TryGetValue(target, out var ci))View on GitHub (pinned to 96fad776d2)