stride3d/stride · error · NotImplementedException

Attribute {attribute} is not supported

Error message

Attribute {attribute} is not supported

What it means

ProcessAttributes analyzes cbuffer member attributes (currently Link and Color). Inside the Link case, the first attribute parameter must be either a StringLiteral or an Identifier; anything else (e.g. a numeric literal, expression, or missing/malformed parameter) falls into the else branch and throws NotImplementedException naming the attribute. It is a 'parameter shape not implemented' guard, not a general unsupported-attribute message.

Solutions

  1. Pass the Link parameter as a quoted string or a bare identifier, e.g. [Link("MyParams")] or [Link(MyParams)].
  2. Verify the referenced symbol resolves in the shader's inheritance/composition context (an Identifier that cannot resolve throws InvalidOperationException before this point).
  3. If a new parameter kind is needed, extend the switch in ProcessAttributes (ShaderElements.cs:269) to handle that literal type.

Example fix

// before
[Link(0)]
struct MyCBuffer { ... };
// after
[Link("0")]
struct MyCBuffer { ... };
Defensive patterns

Strategy: validation

Validate before calling

foreach (var attr in attributes ?? new())
    if (attr is AnyShaderAttribute a && a.Name == "Link"
        && a.Parameters.Count > 0
        && a.Parameters[0] is not (StringLiteral or Identifier))
        throw new FormatException("[Link] parameter must be a string literal or identifier");

Type guard

bool HasValidLinkParameter(ShaderAttribute attr) =>
    attr is AnyShaderAttribute { Name: "Link", Parameters.Count: > 0 } a
    && a.Parameters[0] is StringLiteral or Identifier;

Try / catch

try { result = CBuffer.ProcessAttributes(table, context, info, attributes); }
catch (NotImplementedException ex) { reportDiagnostic(info, ex.Message); }

Prevention

When it happens

Trigger: Declaring a cbuffer member with [Link] whose first parameter is neither a quoted string nor an identifier, e.g. [Link(42)] or [Link(some.expr)] in SDSL source.

Common situations: Hand-written or code-generated SDSL with an incorrectly typed Link argument; API changes where Link used to accept other literal kinds; copy-pasted attributes from other shader languages.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

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

                                        result.LinkId = linkLiteralSymbol.IdRef;
                                    }
                                    else
                                    {
                                        result.LinkName = linkLiteral.Value;
                                    }
                                }
                                else if (anyAttribute.Parameters[0] is Identifier identifier)
                                {
                                    if (!table.TryResolveSymbol(identifier.Name, out var linkSymbol))
                                    {
                                        throw new InvalidOperationException();
                                    }
                                    linkSymbol = ShaderDefinition.ImportSymbol(table, context, linkSymbol);
                                    result.LinkId = linkSymbol.IdRef;
                                }
                                else
                                {
                                    throw new NotImplementedException($"Attribute {attribute} is not supported");
                                }
                                break;
                            }
                        case "Color":
                            result.Color = true;
                            break;
                    }
                }
            }
        }

        return result;
    }

    public override void ProcessSymbol(SymbolTable table, SpirvContext context)
    {
        base.ProcessSymbol(table, context);
        foreach (var cbMember in Members)

View on GitHub (pinned to 96fad776d2)