biomejs/biome · error

empty file

Error message

empty file

What it means

Panic inside the CSS format-on-type handler (css.rs:645). When an editor sends a textDocument/onTypeFormatted request, Biome locates the token at the cursor with tree.token_at_offset(offset); TokenAtOffset::None means the tree contains no token at all, i.e. the document is empty. Despite the 'File is empty, do nothing' comment, the arm panics instead of returning a no-op, so an on-type format request against an empty CSS document crashes this code path.

Source

Thrown at crates/biome_service/src/file_handlers/css.rs:645

    settings: &SettingsWithEditor,
    offset: TextSize,
    workspace_db: WorkspaceDb,
) -> Result<Printed, WorkspaceError> {
    let options = resolve_format_options(biome_path, document_file_source, settings, &workspace_db);

    let tree = parse.syntax(&workspace_db);

    let range = tree.text_range_with_trivia();
    if offset < range.start() || offset > range.end() {
        return Err(WorkspaceError::FormatError(FormatError::RangeError {
            input: TextRange::at(offset, TextSize::from(0)),
            tree: range,
        }));
    }

    let token = match tree.token_at_offset(offset) {
        // File is empty, do nothing
        TokenAtOffset::None => panic!("empty file"),
        TokenAtOffset::Single(token) => token,
        // The cursor should be right after the closing character that was just typed,
        // select the previous token as the correct one
        TokenAtOffset::Between(token, _) => token,
    };

    if token.text_trimmed_range().end() != offset {
        return Ok(format_on_type_noop(offset));
    }

    if !matches_on_type_char(token.text_trimmed()) {
        return Ok(format_on_type_noop(offset));
    }

    let root_node = match token.parent() {
        Some(node) => node,
        None => panic!("found a token with no parent"),
    };

View on GitHub (pinned to 405dedb0ff)

Solutions

  1. Update Biome - check newer releases for a fix replacing this panic with a no-op return, and report it at https://github.com/biomejs/biome/issues if still present
  2. On the client side, do not send textDocument/onTypeFormatted while document.getText().length === 0
  3. Return format_on_type_noop(offset) instead of panicking if you maintain a fork: TokenAtOffset::None => return Ok(format_on_type_noop(offset))

Example fix

// before (crates/biome_service/src/file_handlers/css.rs)
TokenAtOffset::None => panic!("empty file"),

// after
TokenAtOffset::None => return Ok(format_on_type_noop(offset)),
Defensive patterns

Strategy: validation

Validate before calling

// LSP client (TypeScript) - skip on-type formatting for empty documents
const text = document.getText();
if (text.length === 0) return; // do not send textDocument/onTypeFormatted

Type guard

const isEmptyDocument = (document: TextDocument): boolean =>
  document.getText().length === 0;

Prevention

When it happens

Trigger: An LSP client sends onTypeFormatted for a CSS document whose text is empty (zero length): the range guard at offset 0 over tree range 0..0 passes, then token_at_offset(0) returns None and panics. Requires the document to contain no tokens; whitespace-only files still return a whitespace token and do not trigger it.

Common situations: Editors that fire on-type formatting as soon as a file is opened or after all content is deleted; LSP middleware or bots replaying onTypeFormatted requests; newly-created empty .css files.

Related errors


AI-assisted analysis of biomejs/biome@405dedb0ff (2026-08-20). Data as JSON: /api/errors/4ec20aeb4b186af6. Report an issue: GitHub.