{"record":{"id":"81fc67fff96bbf60","repo":"biomejs/biome","slug":"empty-file-81fc67","errorCode":null,"errorMessage":"empty file","messagePattern":"empty file","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/biome_service/src/file_handlers/graphql.rs","lineNumber":523,"sourceCode":"    settings: &SettingsWithEditor,\n    offset: TextSize,\n    workspace_db: WorkspaceDb,\n) -> Result<Printed, WorkspaceError> {\n    let options = resolve_format_options(biome_path, document_file_source, settings, &workspace_db);\n\n    let tree = parse.syntax(&workspace_db);\n\n    let range = tree.text_range_with_trivia();\n    if offset < range.start() || offset > range.end() {\n        return Err(WorkspaceError::FormatError(FormatError::RangeError {\n            input: TextRange::at(offset, TextSize::from(0)),\n            tree: range,\n        }));\n    }\n\n    let token = match tree.token_at_offset(offset) {\n        // File is empty, do nothing\n        TokenAtOffset::None => panic!(\"empty file\"),\n        TokenAtOffset::Single(token) => token,\n        // The cursor should be right after the closing character that was just typed,\n        // select the previous token as the correct one\n        TokenAtOffset::Between(token, _) => token,\n    };\n\n    if token.text_trimmed_range().end() != offset {\n        return Ok(format_on_type_noop(offset));\n    }\n\n    if !matches_on_type_char(token.text_trimmed()) {\n        return Ok(format_on_type_noop(offset));\n    }\n\n    let root_node = match token.parent() {\n        Some(node) => node,\n        None => panic!(\"found a token with no parent\"),\n    };","sourceCodeStart":505,"sourceCodeEnd":541,"githubUrl":"https://github.com/biomejs/biome/blob/405dedb0ff65dd29927faf587f6542e3c29db248/crates/biome_service/src/file_handlers/graphql.rs#L505-L541","documentation":"Panic inside the GraphQL format-on-type handler (graphql.rs:523). For a textDocument/onTypeFormatted request, Biome resolves the token at the cursor with tree.token_at_offset(offset); TokenAtOffset::None means the tree has no tokens, i.e. an empty document. The 'File is empty, do nothing' comment is not honored: the arm panics instead of returning a no-op, so on-type formatting an empty GraphQL document crashes this path.","triggerScenarios":"An LSP client sends onTypeFormatted for a zero-length .graphql document: the range check at offset 0 over tree range 0..0 passes, token_at_offset(0) yields None, and the panic fires. Files with at least one token (even whitespace) return a token and skip this arm.","commonSituations":"Editors triggering on-type format on freshly opened empty .graphql/.gql files or after the user deletes all content; automated LSP conformance suites that send onTypeFormatted to empty buffers.","solutions":["Update Biome - if the panic persists, report it at https://github.com/biomejs/biome/issues","Client-side: skip sending textDocument/onTypeFormatted when the document text is empty","In a fork, change the arm to return Ok(format_on_type_noop(offset))"],"exampleFix":"// before\nTokenAtOffset::None => panic!(\"empty file\"),\n\n// after\nTokenAtOffset::None => return Ok(format_on_type_noop(offset)),","handlingStrategy":"validation","validationCode":"// LSP client (TypeScript) - skip on-type formatting for empty GraphQL files\nif (document.getText().length === 0) return;","typeGuard":"const isEmptyDocument = (document: TextDocument): boolean =>\n  document.getText().length === 0;","tryCatchPattern":null,"preventionTips":["Only send textDocument/onTypeFormatted for non-empty documents","Delay format-on-type registration until the first edit lands in a .graphql file","Track upstream fixes for the empty-file on-type panic"],"tags":["graphql","lsp","format-on-type","panic","empty-file"],"backgroundTag":"format-on-type-empty-document","analyzedSha":"405dedb0ff65dd29927faf587f6542e3c29db248","analyzedAt":"2026-08-20T00:25:09.682Z","contentChangedAt":"2026-08-20T00:25:09.682Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}