zed-industries/zed · error

grammar in indent match set has indents_config

Error message

grammar in indent match set has indents_config

What it means

Asserts that every grammar appearing in a tree-sitter indent query match actually has an indents_config. The matches iterator was built with a closure that filters grammars to those having an indents_config, so a grammar reaching the later map without one violates that invariant — effectively a logic error in how matches_with_options filters versus how results are consumed.

Source

Thrown at crates/language/src/buffer.rs:3696

    pub fn indent_size_for_line(&self, row: u32) -> IndentSize {
        indent_size_for_line(self, row)
    }

    /// The indentation that the block comment closed on `position`'s row belongs
    /// at, or `None` if that row is not the closing line of a multi-line block
    /// comment.
    ///
    /// A closing delimiter is conventionally indented one column past its opening
    /// delimiter, so that it lines up with the comment's prefixes:
    ///
    /// ```text
    /// /**
    ///  * doc
    ///  */
    /// ```
    ///
    /// That extra column belongs to the comment rather than to the surrounding
    /// code, which makes the closing row's own indentation a poor basis for
    /// indenting whatever follows it. The opening row's indentation is used
    /// instead.
    ///
    /// Requires the row to hold nothing but whitespace and the closing delimiter,
    /// and `position` to be at or past the end of that delimiter, so that
    /// splitting the delimiter itself is left alone. Also requires the syntax node
    /// containing the delimiter to end there, so that a line which merely looks
    /// like a closing delimiter is not mistaken for one.
    pub fn block_comment_closing_indent(&self, position: Point) -> Option<IndentSize> {
        let row = position.row;
        let indent_len = self.indent_size_for_line(row).len;
        let delimiter_start = Point::new(row, indent_len);
        let language = self.language_scope_at(delimiter_start)?;
        // A few languages describe a string literal in `block_comment` rather
        // than a comment (Python's `"""`), so either scope is accepted. Relying
        // on the override scope keeps this out of the business of guessing at
        // grammar node names.
        if !matches!(language.override_name(), Some("comment" | "string")) {

View on GitHub (pinned to 9d272b0363)

Solutions

  1. Filter grammars consistently: skip grammars whose indents_config is None in the consumption loop too
  2. Verify the grammar registry loaded indent queries for all grammars participating in the buffer
  3. Replace the unwrap with a flat_map over indents_config.as_ref() to make absence a no-op
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/language/src/buffer.rs:3681 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of zed-industries/zed@9d272b0363 (2026-08-20). Data as JSON: /api/errors/9918d4f104b30591. Report an issue: GitHub.