stride3d/stride · error · Exception
Bad token
Error message
Bad token {tok} What it means
The main token() loop of the Preprocessor encountered a token type it has no case for, so it throws a generic Exception("Bad token " + tok). This is a fall-through default in the tokenizer state machine and indicates a token kind the preprocessor cannot handle at top level.
Solutions
- Inspect the offending token text in the message and fix the source at that position
- Update/align the Lexer and Preprocessor versions so token enums match
- Check for binary/corrupted characters in the shader file (encoding issues)
- Catch Exception and log tok for diagnosis
Defensive patterns
Strategy: try-catch
Validate before calling
if (tok.Type == TokenType.INVALID) error(tok.Line, tok.Column, tok.Value as string);
Type guard
bool isHandled(TokenType t) => t is not TokenType.INVALID && Enum.IsDefined(t);
Try / catch
try { foreach (var tok in pp) Process(tok); } catch (Exception e) when (e.Message.StartsWith("Bad token")) { log.Error($"Unhandled token in source: {e.Message}"); } Prevention
- Keep Lexer and Preprocessor token enums in sync
- Sanitize shader files for stray/invalid characters before preprocessing
When it happens
Trigger: A Lexer produces a token type outside the set handled in the switch (e.g. Token.INVALID when CSYNTAX feature handling paths diverge, or a custom lexer emitting unexpected token kinds) — reached via the public Preprocessor token stream API.
Common situations: Custom/patched lexers feeding the preprocessor, corrupted or non-standard shader source producing odd tokens, version drift between lexer and preprocessor token enums.
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
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/1a8f1abb2d809f65.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/CppNet/Preprocessor.cs:1943
return tok;
if (source.isExpanding(m))
return tok;
if (macro(m, tok))
break;
return tok;
case Token.P_LINE:
if (getFeature(Feature.LINEMARKERS))
return tok;
break;
case Token.INVALID:
if (getFeature(Feature.CSYNTAX))
error(tok, (String)tok.getValue());
return tok;
default:
throw new Exception("Bad token " + tok);
// break;
case Token.HASH:
tok = source_token_nonwhite();
// (new Exception("here")).printStackTrace();
switch (tok.getType()) {
case Token.NL:
goto BREAK_LEX; /* Some code has #\n */
case Token.IDENTIFIER:
break;
default:
error(tok,
"Preprocessor directive not a word " +
tok.getText());
return source_skipline(false);
}
int _ppcmd = ppcmds[tok.getText()];
if (_ppcmd == null) {View on GitHub (pinned to 96fad776d2)