stride3d/stride · error · NotImplementedException

Can't parse method attribute

Error message

Can't parse method attribute {anyAttribute} on method {Name}

What it means

ShaderMethod handles a known set of method attributes (domain, partitioning, outputtopology, etc.). When an attribute name reaches the final else with no handler, the compiler does not know what SPIR-V (if anything) to emit and throws NotImplementedException naming the attribute and method.

Solutions

  1. Remove the unsupported attribute from the method.
  2. Replace it with a supported equivalent attribute (see ShaderMethod's handled names in ShaderElements.MethodOrMember.cs).
  3. Implement a handler for the attribute in the compiler if you own the code and SPIR-V supports the corresponding execution mode.

Example fix

// before
[legacyAttribute(4)]
void GSMain(...) {}
// after
void GSMain(...) {} // drop or replace the unsupported attribute
Defensive patterns

Strategy: try-catch

Validate before calling

var handledAttrs = new HashSet<string> { "domain", "partitioning", "outputtopology" };
foreach (var a in method.Attributes)
    if (!handledAttrs.Contains(a.Name)) Console.WriteLine($"Attribute {a.Name} may not be supported");

Try / catch

try { method.Compile(); }
catch (NotImplementedException ex) when (ex.Message.Contains("Can't parse method attribute"))
{
    // remove or replace the unsupported attribute, or add a compiler handler
}

Prevention

When it happens

Trigger: Annotating a shader method with an attribute the SPIR-V backend does not handle, e.g. a legacy D3D attribute or a typo such as [partioning(...)].

Common situations: Porting legacy SDSL/D3D shader code whose attributes were accepted by the older DX backend but have no SPIR-V translation yet.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/e0c050f8f295b527. Report an issue: GitHub.

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs:610

                    }
                    else if (anyAttribute.Name == "outputtopology")
                    {
                        var value = ((StringLiteral)anyAttribute.Parameters[0]).Value;
                        if (value != "line")
                        {
                            // VertexOrderCw/Ccw are only valid on TessellationEvaluation per
                            // SPIR-V spec; route to DSMain (same reason as partitioning above).
                            context.Add(new OpExecutionMode(GetTessEvaluationFunctionId(table, function.Id), ((StringLiteral)anyAttribute.Parameters[0]).Value switch
                            {
                                "triangle_cw" => Specification.ExecutionMode.VertexOrderCw,
                                "triangle_ccw" => Specification.ExecutionMode.VertexOrderCcw,
                                _ => throw new NotSupportedException($"Unsupported output topology value '{((StringLiteral)anyAttribute.Parameters[0]).Value}'"),
                            }, []));
                        }
                    }
                    else
                    {
                        throw new NotImplementedException($"Can't parse method attribute {anyAttribute} on method {Name}");
                    }
                }
            }
        }

        if (Type is not FunctionType ftype)
            throw new InvalidOperationException();

        table.Push(SymbolFrame!);
        builder.BeginFunction(context, function);

        var functionInfo = new OpFunctionMetadataSDSL(Specification.FunctionFlagsMask.None, 0);

        if (IsOverride)
        {
            // Find parent function
            var parentSymbol = table.ResolveSymbol(function.Name);
            // If multiple symbol with same name, find the proper overload (it should have the exact same signature)

View on GitHub (pinned to 96fad776d2)