denisidoro/navi · error
Unable to get variable
Error message
Unable to get variable
What it means
Third field of the `var_stdin` stdin protocol: the variable name. If the payload has selection and query but no trailing variable field, `parts.next()` returns `None` and the `expect` panics with "Unable to get variable".
Source
Thrown at src/commands/preview/var_stdin.rs:19
use clap::Args;
use super::var;
use crate::common::shell::{self, ShellSpawnError, EOF};
use crate::prelude::*;
use std::io::{self, Read};
#[derive(Debug, Clone, Args)]
pub struct Input {}
impl Runnable for Input {
fn run(&self) -> Result<()> {
let mut text = String::new();
io::stdin().read_to_string(&mut text)?;
let mut parts = text.split(EOF);
let selection = parts.next().expect("Unable to get selection").to_owned();
let query = parts.next().expect("Unable to get query").to_owned();
let variable = parts.next().expect("Unable to get variable").trim().to_owned();
let input = var::Input {
selection,
query,
variable,
};
input.run()?;
if let Some(extra) = parts.next() {
if !extra.is_empty() {
print!("");
let mut cmd = shell::out();
cmd.arg(extra);
debug!(?cmd);
cmd.spawn().map_err(|e| ShellSpawnError::new(extra, e))?.wait()?;
}View on GitHub (pinned to f7330b9ad5)
Solutions
- Add the VARIABLE placeholder as the third EOF-separated field in the finder preview command template
- Diff your finder preview config against the one shipped by this CLI version and update it
- Manually pipe all three fields to verify the protocol before re-running the finder
- Swap the `expect` for `ok_or_else(|| anyhow!(...))?` in library code
Example fix
// before
let variable = parts.next().expect("Unable to get variable").trim().to_owned();
// after
let variable = parts.next().ok_or_else(|| anyhow!("Unable to get variable from stdin payload"))?.trim().to_owned(); Defensive patterns
Strategy: validation
Validate before calling
let fields: Vec<&str> = text.split(EOF).collect();
if fields.len() < 3 {
eprintln!("stdin payload missing variable field (need 3 EOF-separated fields)");
} Type guard
fn has_variable(text: &str) -> bool {
text.split(EOF).nth(2).map_or(false, |v| !v.trim().is_empty())
} Try / catch
let variable = text.split(EOF).nth(2)
.map(str::trim)
.filter(|v| !v.is_empty())
.ok_or_else(|| anyhow!("no variable in stdin payload"))?;
// guard the payload shape before constructing var::Input Prevention
- Include the VARIABLE placeholder as the trailing field in finder preview templates
- Diff your preview config against the version shipped by the CLI after upgrades
- Write a small test that pipes all three fields into the preview command
- Treat '2 fields received' as a config-drift signal
When it happens
Trigger: The stdin payload ended after the query field — the finder preview template omitted the VARIABLE placeholder or trailing EOF-separated field.
Common situations: Partial migration of the finder preview command when the protocol grew to three fields; a preview invocation copy-pasted from an older config; template whitespace/quoting dropping the last field.
Related errors
- Unable to get selection
- Unable to get query
- Unable to process value
- No variables received from finder
- Unable to parse {path}
AI-assisted analysis of denisidoro/navi@f7330b9ad5 (2026-09-03).
Data as JSON: /api/errors/b74e1be2233f816c.
Report an issue: GitHub.