stride3d/stride · error · NotImplementedException
unknown accessor on type in expression
Error message
unknown accessor {accessor} on type {currentValueType} in expression {this} What it means
The default arm of the accessor-kind switch in the SPIR-V expression compiler. When an accessor (indexer/member/swizzle/postfix already handled) falls through with an unrecognized Accessor subtype on a given currentValueType, this NotImplementedException fires at Expression.cs:1470, including the accessor, type, and full expression in the message.
Solutions
- Identify the accessor kind from the message and add a corresponding case to the switch before `default` in Expression.cs.
- Check whether the AST was produced by a mismatched parser version; regenerate it with the matching Stride.Shaders version.
- If the expression itself is wrong, rewrite the shader expression using supported accessors (indexing, member access, swizzle, ++/--).
Example fix
// before default: throw new NotImplementedException(...); // after case NewAccessorKind na: /* compile it */ break; default: throw new NotImplementedException(...);
Defensive patterns
Strategy: try-catch
Validate before calling
// assert every accessor kind is handled before compiling
if (accessor is not (Indexer or Swizzle or Member or PostFix))
throw new ShaderCompileHint($"Unhandled accessor {accessor.GetType().Name}"); Type guard
static bool IsHandledAccessor(Accessor a) => a is Indexer or Swizzle or Member or PostFix;
Try / catch
try { result = CompileExpression(expr, table, compiler); }
catch (NotImplementedException ex) when (ex.Message.StartsWith("unknown accessor"))
{ diagnostics.Report(expr.Info, ex.Message); } Prevention
- Update the compiler switch whenever a new Accessor subclass is added to the AST.
- Avoid hand-building or deserializing ASTs across different compiler versions.
- Add an exhaustive switch / exhaustive-match test over all accessor kinds.
When it happens
Trigger: An Accessor kind other than Indexer/Swizzle/Member/PostFix (or a kind/type combination not covered by the earlier cases) is processed by CompileImpl — only reachable via new accessor types or hand-built ASTs.
Common situations: Encountered while extending the SDSL AST with a new accessor kind that wasn't added to the compiler switch, or after deserializing an AST produced by a different compiler version.
Related errors
- Unsupported base type
- Unsupported type for non-pointer indexer
- Unsupported postfix operator
- Unsupported interlocked operation
- 64bit integers
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/aeb08132e430f89b.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs:1470
// This is what this chain return (value before modification)
result = builder.AsValue(context, result);
// Use integer so that it gets converted to proper type according to expression type
var constant1 = context.CompileConstant(1);
var modifiedValue = builder.BinaryOperation(table, context, result, postfix.Operator switch
{
Operator.Inc => Operator.Plus,
Operator.Dec => Operator.Minus,
_ => throw new NotSupportedException($"Unsupported postfix operator {postfix.Operator}"),
}, constant1, Info);
// We store the modified value back in the variable
builder.Insert(new OpStore(resultPointer.Id, modifiedValue.Id, null, []));
break;
}
default:
throw new NotImplementedException($"unknown accessor {accessor} on type {currentValueType} in expression {this}");
}
currentValueType = accessor.Type!;
// only if OpAccessChain is emitted (otherwise there is no value)
if (compiler != null && accessChainIdCount == 0)
intermediateValues![1 + i] = result;
}
if (compiler != null)
EmitOpAccessChain(accessChainIds, Accessors.Count - 1);
Type = currentValueType;
return result;
}
private void TextureGenerateImageOperands(SpirvValue? lod, SpirvValue? offset, SpirvValue? sampleIndex, out ImageOperandsMask imask, out EnumerantParameters imParams)
{View on GitHub (pinned to 96fad776d2)