{"record":{"id":"66471d04272c6f59","repo":"stride3d/stride","slug":"symbol-symbol-could-not-be-imported-because-it-was-not-found","errorCode":null,"errorMessage":"Symbol {symbol} could not be imported because it was not found in its owner type {symbol.OwnerType}","messagePattern":"Symbol (.+?) could not be imported because it was not found in its owner type (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs","lineNumber":632,"sourceCode":"                            if (c.Symbol.IdRef == 0 && context != null)\n                            {\n                                // Emit symbol\n                                var shaderId = context.GetOrImportShader(symbol.OwnerType);\n                                context.ImportShaderVariable(shaderId, ref c.Symbol, c.Flags);\n                            }\n\n                            symbol.IdRef = c.Symbol.IdRef;\n                            if (!isCurrentShader)\n                                symbol = symbol with { MemberAccessWithImplicitThis = c.Symbol.Type };\n\n                            return symbol;\n                        }\n                    }\n                }\n            }\n        }\n\n        throw new InvalidOperationException($\"Symbol {symbol} could not be imported because it was not found in its owner type {symbol.OwnerType}\");\n    }\n\n    /// <summary>\n    /// Try to resolve a symbol in shader or inherited shader. If <see cref=\"importContext\"/> is null, you can use this method without importing type or symbol in a context (useful for type evaluation).\n    /// </summary>\n    /// <param name=\"symbolTable\"></param>\n    /// <param name=\"importContext\">If not null, the method or symbol will be imported in this context.</param>\n    /// <param name=\"id\"></param>\n    /// <param name=\"symbol\"></param>\n    /// <returns></returns>\n    internal bool TryResolveSymbol(int id, [MaybeNullWhen(false)] out Symbol symbol)\n    {\n        if (TryResolveSymbolNoRecursion(id, out symbol))\n            return true;\n\n        // Process inherited classes\n        // note: since it contains all indirectly inherited method too, which is why it is splitted with TryResolveSymbolNoRecursion\n        foreach (var inheritedShader in InheritedShaders)","sourceCodeStart":614,"sourceCodeEnd":650,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs#L614-L650","documentation":"Thrown as an InvalidOperationException during symbol import resolution: the parser tried to resolve a shader symbol (method or variable, including constant-buffer members) against its declared owner type, but no member with a matching SymbolID and type exists in that owner. This signals a broken or stale symbol table entry — the symbol's recorded OwnerType no longer contains the symbol, so import cannot proceed.","triggerScenarios":"Calling the symbol-import routine with a Symbol whose OwnerType.Methods/Variables (or constant-buffer Members) do not contain an entry matching symbol.Id and symbol.Type — e.g. after a shader was recompiled or its type layout changed while cached symbols still point at the old owner.","commonSituations":"Stale shader caches after editing a shader class (renaming/removing a member that other shaders still reference); importing a method/variable via inheritance bases where the base class was rebuilt; mismatched overload resolution where the recorded symbol ID no longer matches any method signature in the owner type.","solutions":["Clear/regenerate the shader symbol cache so symbols are re-collected from the current owner types.","Check the shader source for a renamed or removed member and update all references to match the owner type's current members.","Verify inheritance chains: ensure the base shader that actually declares the member is the recorded OwnerType.","If writing parser code, guard with TryResolveSymbol (the public wrapper) instead of calling the throwing internal import path directly."],"exampleFix":"// before: importing a symbol whose owner no longer has the member\nsymbolTable.ImportSymbol(staleSymbol);\n// after: resolve first, only import when found\nif (!symbolTable.TryResolveSymbol(ref staleSymbol, importContext))\n    throw new InvalidOperationException($\"Member '{staleSymbol}' no longer exists on {staleSymbol.OwnerType}; recompile the defining shader\");","handlingStrategy":"validation","validationCode":"// Resolve before importing; avoid the throwing path\nif (symbol.OwnerType.Methods.Any(m => m.Symbol.Id == symbol.Id && m.Symbol.Type == symbol.Type) ||\n    symbol.OwnerType.Variables.Any(v => v.Symbol.Id == symbol.Id && v.Symbol.Type == symbol.Type))\n{\n    symbolTable.ImportSymbol(ref symbol);\n}","typeGuard":"static bool IsResolvableInOwner(Symbol s) =>\n    s.OwnerType != null &&\n    (s.Type is FunctionType\n        ? s.OwnerType.Methods.Any(m => m.Symbol.Id == s.Id && m.Symbol.Type == s.Type)\n        : s.OwnerType.Variables.Any(v => v.Symbol.Id == s.Id && v.Symbol.Type == s.Type));","tryCatchPattern":"try\n{\n    symbolTable.ImportSymbol(ref symbol);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"could not be imported\"))\n{\n    logger.Warn($\"Stale symbol {symbol}: {ex.Message}. Recompiling owner shader.\");\n    RecompileOwner(symbol.OwnerType);\n}","preventionTips":["Invalidate cached symbols whenever a defining shader is recompiled or edited.","Always call TryResolveSymbol before the throwing import path.","Keep symbol OwnerType pointing at the shader that actually declares the member."],"tags":["shader-parsing","symbol-resolution","internal-error"],"backgroundTag":"entity-not-found","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}