stride3d/stride · error · Exception

Internal error: Unknown directive

Error message

Internal error: Unknown directive {tok}

What it means

Inside directive processing, the preprocessor looked up a directive name but found no handler case for it. Since genuine unknown directives are rejected earlier, reaching this throw means an internal dispatch inconsistency and it is thrown unconditionally as a fatal Exception.

Solutions

  1. Add the missing switch case for the directive in the Preprocessor source
  2. Remove the directive from the directive map if it should be treated as unknown
  3. Update CppNet to a version where directive dispatch is consistent

Example fix

// before
// no case for mydir
// after
case "mydir":
    handleMyDir();
    break;
Defensive patterns

Strategy: try-catch

Validate before calling

if (!directiveHandlers.ContainsKey(directiveName)) return SkipLine();

Try / catch

try { ProcessDirectives(); } catch (Exception e) when (e.Message.StartsWith("Internal error")) { log.Error($"Directive dispatch bug: {e.Message}"); }

Prevention

When it happens

Trigger: A recognized #directive is mapped but its handling case is missing — e.g. a directive added to the directive map without adding the corresponding case in the switch, hit while processing # lines in shader source.

Common situations: Custom forks of CppNet adding new directives incompletely; version mismatch between directive registration and dispatch switch after upstream changes.

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/ba20c388f4c9a782. Report an issue: GitHub.

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/CppNet/Preprocessor.cs:2140

                            if(!isActive())
                                return source_skipline(false);
                            return pragma();
                        // break;

                        case PP_IMPORT:
                            if(!isActive())
                                return source_skipline(false);
                            else
                                return import();

                        default:
                            /* Actual unknown directives are
                             * processed above. If we get here,
                             * we succeeded the map lookup but
                             * failed to handle it. Therefore,
                             * this is (unconditionally?) fatal. */
                            // if (isActive()) /* XXX Could be warning. */
                            throw new Exception(
                                    "Internal error: Unknown directive "
                                    + tok);
                        // return source_skipline(false);
                    }
                BREAK_PP: ;
                    break;


			}
    BREAK_LEX: ;
		}
	}

    private Token import()
    {
        return include(false, true);
    }

View on GitHub (pinned to 96fad776d2)