stride3d/stride · error · NotImplementedException
Exception of type 'System.NotImplementedException' was…
Error message
Exception of type 'System.NotImplementedException' was thrown.
What it means
LiteralParsers.Match parses floating-point literal suffixes. The scanner first accepts any of f, f16, f32, f64, d, h via Tokens.AnyOf, then maps the matched string to a Suffix. Because AnyOf already restricts the input to six known suffixes, the switch's default arm is defensively unreachable; if it is ever hit (inconsistent tokenizer vs. switch) a bare NotImplementedException is thrown.
Solutions
- Ensure every string in the AnyOf list ([f, f16, f32, f64, d, h]) has a matching case in the switch (LiteralParsers.cs:315-324).
- If adding a new suffix (e.g. 'df'), add both the AnyOf entry and a Suffix case.
- As a hardening measure, return a parse error instead of throwing so malformed suffixes produce a diagnostic.
Example fix
// before
var matched = Tokens.AnyOf(["f", "f16", "f32", "f64", "d", "h", "df"], ...);
suffix = matched switch { "f16" or "h" => ..., _ => throw new NotImplementedException() };
// after
suffix = matched switch
{
"f16" or "h" => new(16, true, true),
"f32" or "f" => new(32, true, true),
"f64" or "d" or "df" => new(64, true, true),
_ => throw new NotImplementedException()
}; Defensive patterns
Strategy: validation
Validate before calling
var known = new[] { "f", "f16", "f32", "f64", "d", "h" };
if (!known.Contains(candidate)) return false; // not a float suffix; let another parser try Type guard
bool IsKnownFloatSuffix(string s) => s is "f" or "f16" or "f32" or "f64" or "d" or "h";
Try / catch
try { matched = parser.Match(ref scanner, result, out suffix); }
catch (NotImplementedException ex) { reportParseError(scanner.Location, "Unknown float literal suffix", ex); } Prevention
- Keep the AnyOf suffix list and the switch mapping in sync — change them together.
- Add unit tests that drive the parser through every accepted suffix string.
- On library upgrade, re-run literal parsing tests before shipping new suffix support.
When it happens
Trigger: Only via an internal inconsistency: AnyOf matches a suffix string that the switch does not handle — e.g. someone adds a new suffix to the AnyOf list (or changes scanner behavior) without adding a corresponding switch case.
Common situations: Library development: extending the float suffix list in Tokens.AnyOf but forgetting the mapping; custom scanners overriding matching behavior.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- EffectCompiler returned no shader and no compilation error.
- Cannot call PostProcess on voxel texture with unknown…
- Property unsupported by method UpdateValueFromComponent.
- Property unsupported by method OnRGBAValueChanged.
- Property unsupported by method OnHSVValueChanged.
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/d0d009409899582a.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs:323
scanner.Advance(match.Length);
return true;
}
return false;
}
public readonly bool Match<TScanner>(ref TScanner scanner, ParseResult result, out Suffix suffix, in ParseError? orError = null)
where TScanner : struct, IScanner
{
suffix = new(32, false, false);
if (Tokens.AnyOf(["f", "f16", "f32", "f64", "d", "h"], ref scanner, out var matched, advance: true))
{
suffix = matched switch
{
"f16" or "h" => new(16, true, true),
"f32" or "f" => new(32, true, true),
"f64" or "d" => new(64, true, true),
_ => throw new NotImplementedException()
};
return true;
}
else return false;
}
}
public readonly record struct IntegerSuffixParser() : ILiteralParser<Suffix>
{
public static bool TryMatchAndAdvance<TScanner>(ref TScanner scanner, string match)
where TScanner : struct, IScanner
{
if (Tokens.Literal(match, ref scanner))
{
scanner.Advance(match.Length);
return true;
}
return false;View on GitHub (pinned to 96fad776d2)