{"record":{"id":"23490f303b0669b6","repo":"stride3d/stride","slug":"buildinheritancelistwithoutself-opmixininheritsdsl","errorCode":null,"errorMessage":"BuildInheritanceListWithoutSelf: OpMixinInheritSDSL references shader ID {inherit.Shader} not found in shaderMapping (shader: {classSource.ToClassNameWithGenerics()}, mapping keys: [{string.Join(\", \", shaderMapping.Keys)}])","messagePattern":"BuildInheritanceListWithoutSelf: OpMixinInheritSDSL references shader ID (.+?) not found in shaderMapping \\(shader: (.+?), mapping keys: \\[(.+?)\\]\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs","lineNumber":183,"sourceCode":"        ConstantExpression ResolveGenericArg(ConstantExpression arg)\n        {\n            // First substitute the current shader's own generics\n            if (resolvedGenericArgs != null && declaringClassName != null)\n                arg = arg.Substitute(declaringClassName, resolvedGenericArgs);\n            // Then resolve any remaining GenericParamExpr by looking up parent imports\n            if (arg is GenericParamExpr genParam && importArgsByName.TryGetValue(genParam.DeclaringClass, out var parentArgs) && genParam.Index < parentArgs.Length)\n                arg = ResolveGenericArg(parentArgs[genParam.Index]);\n            return arg;\n        }\n\n        // Check inheritance\n        foreach (var i in declaringContext)\n        {\n            if (i.Op == Op.OpMixinInheritSDSL && (OpMixinInheritSDSL)i is { } inherit)\n            {\n                if (!shaderMapping.TryGetValue(inherit.Shader, out var shaderName))\n                {\n                    throw new InvalidOperationException($\"BuildInheritanceListWithoutSelf: OpMixinInheritSDSL references shader ID {inherit.Shader} not found in shaderMapping (shader: {classSource.ToClassNameWithGenerics()}, mapping keys: [{string.Join(\", \", shaderMapping.Keys)}])\");\n                }\n\n                // Resolve generic arguments: substitute own generics + resolve parent references\n                if (shaderName.GenericArguments.Length > 0)\n                {\n                    var remappedArgs = new ConstantExpression[shaderName.GenericArguments.Length];\n                    for (int index = 0; index < remappedArgs.Length; index++)\n                        remappedArgs[index] = ResolveGenericArg(shaderName.GenericArguments[index]);\n                    shaderName = shaderName with { GenericArguments = remappedArgs };\n                }\n\n                BuildInheritanceListIncludingSelf(shaderLoader, topLevelContext, shaderName, macros, inheritanceList, resolveStep);\n            }\n        }\n    }\n\n    public static ShaderClassInstantiation ConvertToShaderClassSource(SpirvContext declaringContext, OpImportShaderSDSL importShader)\n    {","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs#L165-L201","documentation":"BuildInheritanceListWithoutSelf resolves OpMixinInheritSDSL instructions through a shaderMapping dictionary built from OpImportShaderSDSL instructions. When an inherit instruction references a shader ID that has no corresponding import entry, the internal mapping invariant is broken and an InvalidOperationException is thrown, including the current shader name and the keys actually present.","triggerScenarios":"A shader in the declaring context inherits (OpMixinInheritSDSL) from a shader ID that was never emitted as OpImportShaderSDSL in the same context — e.g. inheriting from the shader itself, a forward reference, or an ID that belongs to another buffer.","commonSituations":"SDSL mixin code inheriting from a class that was not imported in that translation unit; a compiler bug or stale cached SPIR-V buffer where imports were dropped; cyclic mixin inheritance where the parent was pruned from imports.","solutions":["Add the missing import for the inherited shader in the SDSL source so an OpImportShaderSDSL is emitted.","Regenerate the SPIR-V buffer (clear the shader cache) if it is stale and lacks the import instruction.","If you manipulate the SpirvContext programmatically, ensure every OpMixinInheritSDSL's Shader ID has a matching OpImportShaderSDSL entry in shaderMapping."],"exampleFix":"// before (SDSL)\nmixin Inheritor : Parent<float>\n// after (add the import above the mixin)\nimport Parent;\nmixin Inheritor : Parent<float>","handlingStrategy":"validation","validationCode":"// before building: every OpMixinInheritSDSL.Shader id must exist in the import set\nvar importIds = declaringContext.Where(i => i.Op == Op.OpImportShaderSDSL).Select(i => i.ResultId).ToHashSet();\nvar inheritIds = declaringContext.Where(i => i.Op == Op.OpMixinInheritSDSL).Select(i => i.Word(3)).Where(id => !importIds.Contains(id));\nif (inheritIds.Any()) throw new InvalidOperationException($\"Inherited shader ids not imported: {string.Join(\",\", inheritIds)}\");","typeGuard":null,"tryCatchPattern":"try { SpirvBuilder.BuildInheritanceListWithoutSelf(loader, ctx, source, macros, declaringContext, list, step); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"not found in shaderMapping\")) { log.LogError(ex, \"Missing import for inherited mixin in {Shader}\", source.ClassName); }","preventionTips":["Always import a shader before inheriting from it in SDSL","Avoid self-referential or cyclic mixin inheritance","Regenerate cached SPIR-V buffers after changing imports"],"tags":["spirv","inheritance","mixin","missing-reference"],"backgroundTag":"resource-not-found","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}