stride3d/stride · error · NotImplementedException
Unsupported context dependent number with type
Error message
Unsupported context dependent number with type {typeInst.Op} What it means
When resolving an OpConstant/OpSpecConstant, the type instruction found for the constant's type id must be OpTypeInt or OpTypeFloat for the value to be extracted as a number. Any other type opcode (OpTypeBool, OpTypeVector, OpTypePointer, etc.) throws NotImplementedException naming the type opcode. Composites are handled earlier in the method, so reaching here means an unexpected scalar-ish type.
Solutions
- Validate the SPIR-V module so constants of non-numerical types are not emitted as OpConstant (e.g. pointers use OpConstantNull/OpUndef paths)
- Add a case in TryGetConstantValue for the unexpected type opcode (e.g. route OpTypeBool to true/false handling)
- Check for parser bugs causing type-id lookup to resolve to the wrong instruction (dump typeInst.Op at the throw site)
Example fix
// before
else
throw new NotImplementedException($"Unsupported context dependent number with type {typeInst.Op}");
// after
else if (typeInst.Op == Specification.Op.OpTypeBool)
{ value = operand.ToLiteral<byte>() != 0; return true; }
else
throw new NotImplementedException($"Unsupported context dependent number with type {typeInst.Op}"); Defensive patterns
Strategy: validation
Validate before calling
// confirm a constant's result type is a numeric type before evaluation
bool IsNumericConstant(SpirvBuffer buffer, Instruction constant)
{
var typeId = constant.Data.Memory.Span[1];
return buffer.TryGetInstructionById(typeId, out var t) &&
t.Op is Specification.Op.OpTypeInt or Specification.Op.OpTypeFloat;
} Try / catch
try
{
context.TryGetConstantValue(id, out var value, out var typeId);
}
catch (NotImplementedException ex) when (ex.Message.Contains("Unsupported context dependent number"))
{
// handle composite/null constants through the dedicated paths instead
} Prevention
- Never emit OpConstant for pointer/struct/vector types — use OpConstantNull/OpConstantComposite
- Validate the module so type ids referenced by constants resolve to int/float/composite/bool types
- Check parser ordering so composite constants are matched before falling into the numeric path
When it happens
Trigger: A constant instruction whose Result Type is not an int/float/composite/bool type — e.g. an OpConstant typed as OpTypePointer, OpTypeStruct, or a mis-registered type id pointing to a non-number type instruction.
Common situations: Malformed or hand-written SPIR-V where constants are typed incorrectly; parser state where a type id resolves to the wrong instruction; modules with constants of types the evaluator never expected to see here.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Can't process argument
- Cast from to is not implemented
- Cast from to is not implemented
- Exception of type 'System.NotImplementedException' was…
- System-value Semantic not implemented
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/ce2f26863dfb3371.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs:240
{ Width: 64, Signedness: 1 } => operand.ToLiteral<long>(),
_ => throw new NotImplementedException($"Unsupported int width {type.Width}"),
};
return true;
}
else if (typeInst.Op == Specification.Op.OpTypeFloat)
{
var type = new OpTypeFloat(typeInst);
value = type switch
{
{ Width: 16 } => operand.ToLiteral<Half>(),
{ Width: 32 } => operand.ToLiteral<float>(),
{ Width: 64 } => operand.ToLiteral<double>(),
_ => throw new NotImplementedException($"Unsupported float width {type.Width}"),
};
return true;
}
else
throw new NotImplementedException($"Unsupported context dependent number with type {typeInst.Op}");
}
throw new Exception("Cannot find type instruction for id " + typeId);
}
public SpirvValue CreateDefaultConstantComposite(SymbolType type)
{
// TODO: cache results (either here or even more generally for any composite constant even if non-zero)
return new(Buffer.AddData(new OpConstantNull(GetOrRegister(type), Bound++)));
}
public SpirvValue CreateConstantCompositeVectorRepeat(Literal literal, int size)
{
var value = CompileConstantLiteral(literal);
if (size == 1)
return value;
var type = new VectorType((ScalarType)ReverseTypes[value.TypeId], size);View on GitHub (pinned to 96fad776d2)