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

  1. Ensure ImportSymbol (or equivalent creation pass) runs for the symbol before EmitSymbol is called
  2. Check earlier compilation errors — a failed import often leaves IdRef at 0; fix the root cause first
  3. 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

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


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)