stride3d/stride · error · InvalidOperationException
Could not find cbuffer member link info for
Error message
Could not find cbuffer member link info for {context.Names[cbuffer.VariableId]}; it should have been generated during MergeCBuffers What it means
During SPIR-V cbuffer reflection, ShaderMixer.ComputeCBufferReflection requires per-member layout metadata that MergeCBuffers was supposed to record for each composition cbuffer variable. If the dictionary lookup fails, the mixer's internal invariant ('metadata generated during MergeCBuffers') has been violated, so it throws InvalidOperationException naming the cbuffer.
Solutions
- Run the standard ShaderMixer.MergeSDSL pipeline end-to-end so MergeCBuffers executes before ComputeCBufferReflection
- Check for earlier exceptions or result errors from MergeCBuffers that were ignored, leaving the metadata dictionary incomplete
- If using a custom pipeline, replicate the MergeCBuffers step before invoking cbuffer reflection
- Update Stride packages to a consistent version so mixer phases match
Example fix
// before: calling reflection without merging var reflection = mixer.ComputeCBufferReflection(context, cbuffers, cbufferMemberMetadata); // after: ensure merge phase ran first var mergeResult = mixer.MergeSDSL(mixinTree, ...); // runs MergeCBuffers internally if (mergeResult.HasErrors) throw mergeResult.Exceptions.First();
Defensive patterns
Strategy: validation
Validate before calling
if (!mergeResult.HasErrors && cbufferVariableIds.All(id => cbufferMemberMetadata.ContainsKey(id)))
reflection = mixer.ComputeCBufferReflection(context, cbuffers, cbufferMemberMetadata); Try / catch
try { reflection = mixer.ComputeCBufferReflection(...); }
catch (InvalidOperationException ex) when (ex.Message.Contains("cbuffer member link info")) { logMergePipelineBug(ex); throw; } Prevention
- Always run the full MergeSDSL pipeline; never call reflection phases standalone
- Log and inspect errors from MergeCBuffers before proceeding
- Keep Stride.Shaders.* package versions in sync
When it happens
Trigger: Calling ShaderMixer.MergeSDSL on a shader tree where a composition variable's cbuffer member-link metadata was never produced by MergeCBuffers — e.g. a cbuffer variable that survived mixing without passing through the merge step, or a mixer code path/pipeline stage run out of order (reflection executed before the CBuffers merge phase).
Common situations: Custom or forked shader compiler pipelines that invoke ComputeCBufferReflection/ComputeCBufferReflectionData directly instead of going through the full MergeSDSL flow; older or mismatched Stride.Shaders assemblies where MergeCBuffers was skipped due to an earlier exception being swallowed; hand-constructed MixinNode trees.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Member was not found in shader
- Unsupported execution model
- [Color] attribute can only be applied on float3/float4…
- Unsupported float vector size
- Unsupported int vector size
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/1f8f6c76c4f0ad2e.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs:446
// Note: MemberIndexOffset is simply a shift in Members index, not something like a byte offset
.Select(x => (
Variable: x,
VariableId: x.Data.IdResult!.Value,
StructTypePtrId: x.Data.IdResultType!.Value,
StructType: context.ReverseTypes[x.Data.IdResultType.Value] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null,
MemberIndexOffset: 0))
.Where(x => x.StructType != null)
.ToList();
foreach (var cbuffer in cbuffers)
{
int constantBufferOffset = 0;
var cb = cbuffer.StructType!;
var structTypeId = context.Types[cb];
var memberInfos = new EffectValueDescription[cb.Members.Count];
if (!cbufferMemberMetadata.TryGetValue(cbuffer.VariableId, out var cbufferMetadata))
throw new InvalidOperationException($"Could not find cbuffer member link info for {context.Names[cbuffer.VariableId]}; it should have been generated during {nameof(MergeCBuffers)}");
for (var index = 0; index < cb.Members.Count; index++)
{
// Properly compute size and offset according to DirectX rules
var member = cb.Members[index];
var memberSize = SpirvBuilder.ComputeBufferOffset(member.Type, member.TypeModifier, ref constantBufferOffset, SpirvBuilder.AlignmentRules.CBuffer).Size;
DecorateMember(context, structTypeId, index, constantBufferOffset, memberSize, member.Type, member.TypeModifier);
var metadata = cbufferMetadata[index];
memberInfos[index] = new EffectValueDescription
{
Type = ConvertType(context, member.Type, member.TypeModifier, SpirvBuilder.AlignmentRules.CBuffer),
RawName = member.Name,
KeyInfo = new EffectParameterKeyInfo { KeyName = metadata.Link },
Offset = constantBufferOffset,
Size = memberSize,View on GitHub (pinned to 96fad776d2)