stride3d/stride · error · InvalidOperationException
Symbol has not been imported or created properly
Error message
Symbol {symbol} has not been imported or created properly What it means
Thrown by EmitSymbol when a symbol's IdRef (its SPIR-V result id) is 0, meaning the symbol was never imported into SPIR-V or created by an earlier compilation pass. The emitter cannot reference a symbol that has no SPIR-V id assigned.
Solutions
- Ensure ImportSymbol (or equivalent creation pass) runs for the symbol before EmitSymbol is called
- Check earlier compilation errors — a failed import often leaves IdRef at 0; fix the root cause first
- Verify symbols are emitted in the correct pass order (types/globals before use sites)
Example fix
// before CompileSymbol(table, builder, context, constantOnly); // ResolvedSymbol never imported // after var imported = ShaderDefinition.ImportSymbol(table, context, resolvedSymbol); // assigns IdRef CompileSymbol(table, builder, context, constantOnly);
Defensive patterns
Strategy: validation
Validate before calling
if (symbol.IdRef == 0)
throw new InvalidOperationException($"Symbol {symbol.Id.Name} was never imported (IdRef=0)"); Type guard
bool IsEmittable(Symbol s) => s.IdRef != 0;
Try / catch
try { EmitSymbol(builder, context, symbol, constantOnly); }
catch (InvalidOperationException ex) { log.Error($"Symbol import missing: {ex.Message}"); throw; } Prevention
- Always run ImportSymbol before emission
- Fail fast on earlier import errors instead of continuing
- Assert IdRef != 0 in debug builds
When it happens
Trigger: Calling EmitSymbol (directly or via CompileSymbol) on a Symbol whose IdRef was never populated by ShaderDefinition.ImportSymbol or the symbol-creation passes, e.g. when a pass that assigns IdRefs was skipped or failed silently.
Common situations: Shaders referencing extern/global variables that failed to import; compilation order issues where a symbol is emitted before its defining shader is imported; symbols created in one CompilerUnit but emitted in another.
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
- spirv_to_dxil_pipeline failed; SPIR-V dumped to
- Can't OpLoad with cbuffer
- Unsupported composite type
- Exception of type 'System.NotImplementedException' was…
- Can't cast from to
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/13aace2e3a79e65e.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs:371
if (value.Type is not PointerType && value.Type != itemType)
value.ProcessSymbol(table, itemType);
}
}
public override string ToString()
=> $"{Values.Count}({string.Join(", ", Values.Select(x => x.ToString()))})";
}
public abstract partial class IdentifierBase(string name, TextLocation info) : Literal(info)
{
public string Name { get; set; } = name;
public Symbol? ResolvedSymbol { get; set; }
public static SpirvValue EmitSymbol(SpirvBuilder builder, SpirvContext context, Symbol symbol, bool constantOnly, int? instance = null)
{
if (symbol.IdRef == 0)
throw new InvalidOperationException($"Symbol {symbol} has not been imported or created properly");
var resultType = context.GetOrRegister(symbol.Type);
var result = new SpirvValue(symbol.IdRef, resultType, symbol.Id.Name);
// Shader symbols are treated separately (we want to return only the shader instance (or this if not specified))
if (symbol.Id.Kind == SymbolKind.Shader)
{
if (constantOnly)
throw new NotImplementedException();
if (instance == null)
instance = builder.Insert(new OpThisSDSL(context.Bound++)).ResultId;
result.Id = instance.Value;
return result;
}
if (symbol.ExternalConstant is { } externalConstant)
{View on GitHub (pinned to 96fad776d2)