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

  1. Replace the offending postfix operator usage in the shader with ++ or --, or rewrite as an explicit assignment (x = x + 1).
  2. Verify the parser only ever produces Inc/Dec postfix operators; fix the parser if another operator leaks through.
  3. 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

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


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)