stride3d/stride · critical · Exception
Constant has no result id
Error message
Constant has no result id
What it means
After AddConstant emits an OpConstant instruction into the SPIR-V buffer, it reads back the instruction's result-id slot (index+1) to return the newly allocated id. If InstructionInfo.GetInfo(data).GetResultIndex fails, the emitted instruction has no result-id operand — which should be impossible for a valid OpConstant — so the library throws 'Constant has no result id'. This indicates the instruction stream or the SPIR-V specification opcode metadata table is inconsistent.
Solutions
- Regenerate/verify the SPIR-V InstructionInfo metadata so OpConstant declares a result-id operand.
- Confirm the Buffer.AddData return value is a complete, well-formed instruction (opcode + word count + operands).
- Update the Stride.Shaders.Parsers package/spec files to a matching version.
Defensive patterns
Strategy: try-catch
Validate before calling
if (!InstructionInfo.GetInfo(data).GetResultIndex(out _)) throw new InvalidOperationException("InstructionInfo metadata does not define a result id for the emitted constant"); Try / catch
try { return context.AddConstant(v); } catch (Exception ex) when (ex.Message == "Constant has no result id") { /* regenerate spec metadata / report toolchain bug */ } Prevention
- Keep SPIR-V specification metadata files in sync with the parser assembly version
- Pin the Stride.Shaders.Parsers package and its spec generator to matching versions
- Sanity-check emitted instruction word counts in CI
When it happens
Trigger: Calling AddConstant when the emitted data's opcode does not resolve to an instruction with a result-id operand — typically because the SPIR-V specification metadata (InstructionInfo) is missing or stale for OpConstant, or the buffer returned corrupted/truncated data.
Common situations: Version skew between the SPIR-V specification generator and the parser assembly; custom builds where InstructionInfo tables were regenerated from an incomplete spec; memory corruption of the emitted OpDataIndex.
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
- Cannot find instruction for id {constantId}
- Cannot find constant instruction for id
- Can't process constant {i.Data.IdResult}
- Cannot modify a YamlAssetMetadata after it has been attached
- Given PropertyKey doesn't have accessor metadata.
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/9cb3f71579932566.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs:32
public Dictionary<(SymbolType Type, object Value), SpirvValue> LiteralConstants { get; } = [];
public int AddConstant<TScalar>(TScalar value)
where TScalar : INumber<TScalar>
{
var data = value switch
{
uint v => Buffer.AddData(new OpConstant<uint>(GetOrRegister(ScalarType.UInt), Bound++, v)),
int v => Buffer.AddData(new OpConstant<int>(GetOrRegister(ScalarType.Int), Bound++, v)),
ulong v => Buffer.AddData(new OpConstant<ulong>(GetOrRegister(ScalarType.UInt64), Bound++, v)),
long v => Buffer.AddData(new OpConstant<long>(GetOrRegister(ScalarType.Int64), Bound++, v)),
Half v => Buffer.AddData(new OpConstant<Half>(GetOrRegister(ScalarType.Half), Bound++, v)),
float v => Buffer.AddData(new OpConstant<float>(GetOrRegister(ScalarType.Float), Bound++, v)),
double v => Buffer.AddData(new OpConstant<double>(GetOrRegister(ScalarType.Double), Bound++, v)),
_ => throw new NotImplementedException()
};
if (InstructionInfo.GetInfo(data).GetResultIndex(out var index))
return data.Memory.Span[index + 1];
throw new Exception("Constant has no result id");
}
public object GetConstantValue(int constantId)
{
if (Buffer.TryGetInstructionById(constantId, out var constant))
{
return ResolveConstantValue(constant);
}
throw new Exception("Cannot find constant instruction for id " + constantId);
}
public bool TryGetConstantValue(int constantId, [MaybeNullWhen(false)] out object value, out int typeId)
{
if (Buffer.TryGetInstructionById(constantId, out var constant))
{
return TryGetConstantValue(constant, out value, out typeId);
}View on GitHub (pinned to 96fad776d2)