nikivdev/code · error

resolver returned empty output for

Error message

resolver {} returned empty output for {}

What it means

A resolver command may exit successfully but produce no stdout; since the resolver's stdout is the selected session/candidate, an empty result is unusable and the tool bails naming the resolver and candidate. This guards against silently proceeding with an empty selection.

Solutions

  1. Ensure the resolver prints the selected candidate to stdout
  2. Fix the resolver script to emit the value (not stderr) and exit 0 only with output
  3. Verify the input fed to the resolver is non-empty before invoking

Example fix

// before
pick | grep -i foo >/dev/null
// after
printf '%s\n' "$pick" | grep -i foo | head -1
Defensive patterns

Strategy: validation

Validate before calling

let out = Command::new(&program).args(&rest).current_dir(&dir).output()?;
let stdout = String::from_utf8_lossy(&out.stdout).trim().to_string();
if !out.status.success() || stdout.is_empty() {
    eprintln!("resolver '{}' produced no usable output", resolver.name);
}

Type guard

fn resolver_output_ok(out: &std::process::Output) -> bool {
    out.status.success() && !String::from_utf8_lossy(&out.stdout).trim().is_empty()
}

Prevention

When it happens

Trigger: Resolver exits 0 but prints nothing: the picker was fed no input lines, a filter matched nothing and the script swallows the exit code, or the script writes results to stderr instead of stdout.

Common situations: Resolver script piping an empty session list into fzf; scripts that `echo` diagnostics but forget to print the selection; quoting bugs redirecting the selection to the wrong stream.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/0569bbe2e20a6b53. Report an issue: GitHub.

Appendix: source

Thrown at src/ai.rs:12598

            .current_dir(target_path)
            .output()
            .with_context(|| format!("failed to run resolver {}", resolver.name))?;
        if !output.status.success() {
            let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();
            bail!(
                "resolver {} failed for {}: {}",
                resolver.name,
                candidate,
                if stderr.is_empty() {
                    format!("exit status {}", output.status)
                } else {
                    stderr
                }
            );
        }
        let stdout = String::from_utf8_lossy(&output.stdout).trim().to_string();
        if stdout.is_empty() {
            bail!(
                "resolver {} returned empty output for {}",
                resolver.name,
                candidate
            );
        }

        return Ok(Some(CodexResolvedReference {
            name: resolver
                .inject_as
                .clone()
                .unwrap_or_else(|| resolver.name.clone()),
            source: "resolver".to_string(),
            matched: candidate.clone(),
            command: Some(command_text),
            output: compact_codex_context_block(&stdout, 12, 1200),
        }));
    }

View on GitHub (pinned to a747e741ae)