stride3d/stride · error · NotSupportedException
Unsupported postfix operator
Error message
Unsupported postfix operator {postfix.Operator} What it means
Thrown when compiling a postfix increment/decrement expression: only Operator.Inc (mapped to Plus) and Operator.Dec (mapped to Minus) are handled. Any other postfix operator reaching this code path throws NotSupportedException at Expression.cs:1461.
Solutions
- Replace the offending postfix operator usage in the shader with ++ or --, or rewrite as an explicit assignment (x = x + 1).
- Verify the parser only ever produces Inc/Dec postfix operators; fix the parser if another operator leaks through.
- If a new postfix operator is intended, add a mapping arm (e.g. to a SPIR-V binary op) in the switch at Expression.cs:1461.
Example fix
// before (internal switch) _ => throw new NotSupportedException(...) // after Operator.Mul => Operator.Times, // example: support the new operator explicitly
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure only ++/-- postfix operators are produced
if (postfix.Operator is not (Operator.Inc or Operator.Dec))
throw new ShaderCompileHint($"Postfix {postfix.Operator} not supported"); Type guard
static bool IsSupportedPostfix(Operator op) => op is Operator.Inc or Operator.Dec;
Try / catch
try { result = CompileExpression(expr, table, compiler); }
catch (NotSupportedException ex) when (ex.Message.Contains("Unsupported postfix operator"))
{ diagnostics.Report(expr.Info, ex.Message); } Prevention
- Use ++ and -- as the only postfix operators in shader code.
- Rewrite exotic postfix forms as explicit assignments (x = x * 2).
- Constrain the parser so only Inc/Dec postfix operators can be constructed.
When it happens
Trigger: A postfix operator token other than ++ or -- survives parsing and reaches the SPIR-V postfix compilation switch — typically only possible via parser bugs or hand-constructed ASTs.
Common situations: Rare in normal shader code; usually encountered after modifying the parser/AST, deserializing an unexpected AST, or an internal compiler invariant break.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Unsupported base type
- Unsupported type for non-pointer indexer
- unknown accessor on type in expression
- Unexpected type for asdouble
- Unsupported element type for abs
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/1828cd67d07f7141.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs:1461
}
var (builder, context) = compiler;
// Emit OpAccessChain with everything so far
EmitOpAccessChain(accessChainIds, i - 1);
var resultPointer = result;
// 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)View on GitHub (pinned to 96fad776d2)