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
- Verify the embedded theme file is plist XML tmTheme format, not VS Code JSON.
- Open the .tmTheme and validate the XML (e.g. `plutil -lint tokyo-night.tmTheme`).
- 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).
- 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
- Keep .tmTheme assets in plist XML format; never substitute VS Code JSON themes
- Validate theme XML in CI (plutil -lint or an XML parse step)
- Wrap Syntect::new in a fallible helper returning Result for user-supplied themes
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
- Task panicked: {}
- failed to build shared blocking HTTP client
- bridge spawn
- initialize through bridge
- authenticate through bridge
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/b3f43dfc8f6f0beb.
Report an issue: GitHub.