xai-org/grok-build · error

Failed to load theme

Error message

Failed to load theme

What it means

`Syntect::new` parses an embedded `.tmTheme` (TextMate theme) bytes with syntect's `ThemeSet::load_from_reader` and panics if parsing fails. Because the theme is compiled into the binary via `include_bytes!`, this normally fails only if the embedded asset is corrupt or in the wrong format. The library uses `.expect` because a bad theme makes syntax highlighting unusable.

Source

Thrown at crates/codegen/xai-grok-markdown/src/syntax.rs:34

    /// The color theme for syntax highlighting.
    pub theme: SyntectTheme,
    /// The syntax definitions (supports 250+ languages via two-face).
    pub syntax_set: SyntaxSet,
}

impl Syntect {
    /// Create a new Syntect instance from theme bytes.
    ///
    /// The theme bytes should be a TextMate `.tmTheme` file.
    ///
    /// # Example
    ///
    /// ```ignore
    /// let syntect = Syntect::new(include_bytes!("assets/tokyo-night.tmTheme"));
    /// ```
    pub fn new(theme_bytes: &[u8]) -> Self {
        let mut cursor = Cursor::new(theme_bytes);
        let theme = ThemeSet::load_from_reader(&mut cursor).expect("Failed to load theme");
        // Use two-face's extended syntax set which includes 250+ languages from bat
        let syntax_set = two_face::syntax::extra_newlines();
        Self { theme, syntax_set }
    }

    /// Find a syntax definition by file path extension.
    pub fn find_syntax_by_file_path(&self, file_path: &Path) -> Option<&SyntaxReference> {
        let ext = file_path.extension()?.to_str()?;
        self.syntax_set.find_syntax_by_extension(ext)
    }

    /// Find a syntax definition by language token (e.g., "rust", "python").
    pub fn find_syntax_by_token(&self, token: &str) -> Option<&SyntaxReference> {
        self.syntax_set.find_syntax_by_token(token)
    }

    /// Create a highlighter for the given file path.
    pub fn highlight_lines_by_file_path(&self, file_path: &Path) -> Option<HighlightLines<'_>> {

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Verify the embedded theme file is plist XML tmTheme format, not VS Code JSON.
  2. Open the .tmTheme and validate the XML (e.g. `plutil -lint tokyo-night.tmTheme`).
  3. Replace with a known-good theme file, or convert the theme with a tool (e.g. `syntect`'s dump tool or a JSON→plist converter).
  4. If themes are user-supplied at runtime, switch to a fallible constructor returning Result instead of expect.

Example fix

// before
let theme = ThemeSet::load_from_reader(&mut cursor).expect("Failed to load theme");
// after
let theme = ThemeSet::load_from_reader(&mut cursor)
    .expect("Failed to load theme: embedded .tmTheme must be valid plist XML");
Defensive patterns

Strategy: validation

Validate before calling

// validate theme bytes are plist XML before constructing Syntect
fn is_plist_theme(bytes: &[u8]) -> bool {
    bytes.starts_with(b"<?xml") || bytes.starts_with(b"\u{feff}<?xml")
}
assert!(is_plist_theme(theme_bytes), "theme must be plist XML tmTheme");

Try / catch

std::panic::catch_unwind(|| Syntect::new(theme_bytes))
    .map_err(|_| HighlightError::BadTheme)?

Prevention

When it happens

Trigger: Passing theme bytes that are not a valid plist/XML tmTheme, truncated bytes, an empty slice, or a theme with unparseable color/scope entries to `Syntect::new`.

Common situations: Replaced tokyo-night.tmTheme with an editor-exported JSON theme (modern VS Code format) instead of the plist XML format syntect expects; build artifact corruption; hand-edited theme file with malformed XML.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/b3f43dfc8f6f0beb. Report an issue: GitHub.