{"record":{"id":"1d0b037d450e9646","repo":"denisidoro/navi","slug":"unable-to-get-selection","errorCode":null,"errorMessage":"Unable to get selection","messagePattern":"Unable to get selection","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/commands/preview/var_stdin.rs","lineNumber":17,"sourceCode":"use clap::Args;\n\nuse super::var;\nuse crate::common::shell::{self, ShellSpawnError, EOF};\nuse crate::prelude::*;\nuse std::io::{self, Read};\n\n#[derive(Debug, Clone, Args)]\npub struct Input {}\n\nimpl Runnable for Input {\n    fn run(&self) -> Result<()> {\n        let mut text = String::new();\n        io::stdin().read_to_string(&mut text)?;\n\n        let mut parts = text.split(EOF);\n        let selection = parts.next().expect(\"Unable to get selection\").to_owned();\n        let query = parts.next().expect(\"Unable to get query\").to_owned();\n        let variable = parts.next().expect(\"Unable to get variable\").trim().to_owned();\n\n        let input = var::Input {\n            selection,\n            query,\n            variable,\n        };\n\n        input.run()?;\n\n        if let Some(extra) = parts.next() {\n            if !extra.is_empty() {\n                print!(\"\");\n\n                let mut cmd = shell::out();\n                cmd.arg(extra);\n                debug!(?cmd);","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/denisidoro/navi/blob/f7330b9ad5bd95b7d1a3c96d00e0a77deb589147/src/commands/preview/var_stdin.rs#L1-L35","documentation":"`var_stdin` is a preview helper that receives a single message on stdin with three fields separated by an EOF marker: selection, query, and variable. `io::stdin().read_to_string` output is split on EOF and the first chunk is the selection; if the stream yields no first chunk (empty stdin) the `expect` panics with \"Unable to get selection\".","triggerScenarios":"Invoking the `var_stdin` preview command (usually from the finder preview pane) with empty or malformed stdin — the feeder process did not write the expected `<selection><EOF><query><EOF><variable>` payload.","commonSituations":"Finder preview integration broken after a version change (preview command signature changed); preview invoked manually/from a script without piping the payload; the finder's preview placeholder expansion failed and produced an empty string.","solutions":["Reproduce the call manually by piping the expected payload: `printf '%s\\x1e%s\\x1e%s' \"$SELECTION\" \"$QUERY\" \"$VARIABLE\" | <bin> preview var-stdin` (adjust EOF byte to the tool's EOF constant)","Check that the finder's preview command template matches the format this version expects (upgrade/downgrade mismatch)","Verify the finder is passing its placeholder variables (SELECTION/QUERY/VARIABLE) into the preview command","Patch the code to return a contextual error instead of panicking on missing stdin fields"],"exampleFix":"// before\nlet selection = parts.next().expect(\"Unable to get selection\").to_owned();\n// after\nlet selection = parts.next().ok_or_else(|| anyhow!(\"Unable to get selection from stdin payload\"))?.to_owned();","handlingStrategy":"validation","validationCode":"let text = io::stdin().read_to_string(&mut String::new())?;\n// count EOF-separated fields before invoking the preview logic\nlet fields: Vec<&str> = text.split(EOF).collect();\nif fields.len() < 3 { eprintln!(\"stdin payload incomplete: expected selection<EOF>query<EOF>variable\"); }","typeGuard":"fn valid_payload(text: &str) -> bool {\n    let mut parts = text.split(EOF);\n    parts.next().map_or(false, |s| !s.is_empty())\n        && parts.next().is_some()\n        && parts.next().is_some()\n}","tryCatchPattern":"let selection = text.split(EOF).next()\n    .filter(|s| !s.is_empty())\n    .ok_or_else(|| anyhow!(\"no selection in stdin payload\"))?;\n// expect() panics cannot be caught with try/catch semantics; guard inputs first","preventionTips":["Keep the finder preview command template in sync with the CLI's stdin protocol","Test the preview command by piping a full three-field payload manually","Upgrade finder and CLI together so placeholder expansion matches","Never invoke the preview command by hand without the payload"],"tags":["rust","panic","stdin","preview"],"backgroundTag":"malformed-stdin-payload","analyzedSha":"f7330b9ad5bd95b7d1a3c96d00e0a77deb589147","analyzedAt":"2026-09-03T13:58:22.429Z","contentChangedAt":"2026-09-03T13:58:22.429Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}