{"record":{"id":"fd26fe59124d3566","repo":"biomejs/biome","slug":"found-a-token-with-no-parent","errorCode":null,"errorMessage":"found a token with no parent","messagePattern":"found a token with no parent","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/biome_service/src/file_handlers/css.rs","lineNumber":662,"sourceCode":"        // 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    };\n\n    if root_node\n        .ancestors()\n        .any(|node: CssSyntaxNode| node.kind().is_bogus())\n    {\n        return Ok(format_on_type_noop(offset));\n    }\n\n    let printed =\n        biome_css_formatter::format_range(options, &tree, root_node.text_trimmed_range())?;\n    Ok(printed)\n}\n\nfn lint(params: LintParams) -> LintResults {\n    let Some(file_source) = params.language.to_css_file_source() else {\n        return LintResults {\n            diagnostics: vec![],","sourceCodeStart":644,"sourceCodeEnd":680,"githubUrl":"https://github.com/biomejs/biome/blob/405dedb0ff65dd29927faf587f6542e3c29db248/crates/biome_service/src/file_handlers/css.rs#L644-L680","documentation":"Panic in the CSS format-on-type handler (css.rs:662). After locating the token under the cursor via token_at_offset, the code calls token.parent(); in a rowan syntax tree the root is always a node, so a token retrieved from token_at_offset normally always has a parent. This branch is a defensive assertion that fires only if the token is detached or the tree root were a bare token - states that should not occur for tokens produced by the parser.","triggerScenarios":"Effectively unreachable through normal LSP traffic: any token returned by tree.token_at_offset(offset) belongs to the tree and has a parent node. Would only fire through API misuse (passing a detached token) or an exotic parse producing a token-rooted tree.","commonSituations":"Almost never seen in practice; appears in crash reports only alongside corrupted or hand-constructed syntax trees, or after internal refactors of the parser.","solutions":["Update to the latest Biome patch release in case the branch was removed or the underlying parse issue fixed","Capture a minimal document plus keystroke that reproduces it and file an issue at https://github.com/biomejs/biome/issues","If you embed biome_service, run the workspace inside catch_unwind so an on-type panic degrades to 'no formatting' instead of taking down the host"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"// LSP client - degrade gracefully if the server dies on an on-type request\ntry {\n  const edits = await client.sendRequest('textDocument/onTypeFormatted', params);\n} catch {\n  // formatting failed server-side; leave the buffer untouched instead of surfacing an error\n}","preventionTips":["Treat onTypeFormatted as best-effort: never block typing on its response","Pin a known-good Biome version and watch release notes for on-type formatting fixes","Report any reproduction to biomejs/biome - this branch is believed unreachable"],"tags":["css","lsp","format-on-type","panic","defensive-check"],"backgroundTag":"syntax-token-no-parent","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"}