{"record":{"id":"2395f9f7ab903d12","repo":"vllm-project/vllm","slug":"name-only-provides-a-unified-parser-the-same","errorCode":null,"errorMessage":"`{name}` only provides a unified parser; the same reasoning parser and tool parser should be specified together","messagePattern":"`(.+?)` only provides a unified parser; the same reasoning parser and tool parser should be specified together","errorType":"exception","errorClass":"ReasoningError","httpStatus":null,"severity":"error","filePath":"rust/src/parser/src/reasoning/mod.rs","lineNumber":133,"sourceCode":"    fn preserve_special_tokens(&self) -> bool {\n        false\n    }\n\n    /// Feed one decoded text delta into the parser.\n    fn push(&mut self, delta: &str) -> Result<ReasoningDelta>;\n\n    /// Flush any buffered partial delimiter state at end of stream.\n    fn finish(&mut self) -> Result<ReasoningDelta> {\n        Ok(ReasoningDelta::default())\n    }\n}\n\n/// Errors produced while creating or running reasoning parsers.\n#[derive(Debug, Error)]\npub enum ReasoningError {\n    #[error(\"tokenizer is missing reasoning delimiter token `{token}`\")]\n    MissingToken { token: String },\n    #[error(\n        \"`{name}` only provides a unified parser; the same reasoning parser and tool parser should be specified together\"\n    )]\n    DummyUnifiedParser { name: String },\n}\n\n#[cfg(test)]\nmod tests;\n","sourceCodeStart":115,"sourceCodeEnd":141,"githubUrl":"https://github.com/vllm-project/vllm/blob/c794754062d49a8fdb63ab3c5215b488b865030c/rust/src/parser/src/reasoning/mod.rs#L115-L141","documentation":"ReasoningError::DummyUnifiedParser is returned when code tries to instantiate a standalone (split) reasoning parser from a parser family that only ships a unified parser. Unified parsers (e.g. granite-style) parse reasoning and tool calls together, so a reasoning-only split instance is meaningless and is rejected at construction.","triggerScenarios":"Calling the reasoning-parser factory with a parser name whose family provides only the unified implementation — i.e. enabling reasoning parsing without the matching tool parser for the same family.","commonSituations":"Configuring --reasoning-parser granite but not --tool-parser granite; library code that enumerates all reasoning parsers and tries to build each one; migrating from split to unified parser API.","solutions":["Specify the same family for both parsers (reasoning AND tool) so the unified parser is constructed","If you only need reasoning output, choose a family that ships a split reasoning parser","When enumerating parsers programmatically, skip families that only expose the unified variant"],"exampleFix":"# before\n--reasoning-parser granite\n\n# after\n--reasoning-parser granite --tool-parser granite","handlingStrategy":"validation","validationCode":"// Unified-only families must be enabled for both parser roles\nlet unified_only = matches!(name.as_str(), \"granite\");\nif unified_only && tool_parser_name != name {\n    return Err(anyhow::anyhow!(\"{name} requires --tool-parser {name} too\"));\n}","typeGuard":"fn is_dummy_unified_reasoning(e: &ReasoningError) -> bool {\n    matches!(e, ReasoningError::DummyUnifiedParser { .. })\n}","tryCatchPattern":"match build_reasoning_parser(name, tokenizer) {\n    Err(ReasoningError::DummyUnifiedParser { name }) => {\n        eprintln!(\"{name} is unified-only; set both --reasoning-parser and --tool-parser to {name}\");\n        std::process::exit(2);\n    }\n    r => r,\n}","preventionTips":["Treat reasoning-parser and tool-parser config as one decision for unified families","Fail config validation early when only one half of a unified family is requested","Document which families are unified-only next to your parser registry"],"tags":["reasoning-parser","tool-parser","unified-parser","configuration","rust"],"backgroundTag":null,"analyzedSha":"c794754062d49a8fdb63ab3c5215b488b865030c","analyzedAt":"2026-08-14T21:17:39.825Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}