can1357/oh-my-pi · error · Error

reference not found: {name}

Error message

reference not found: {name}

What it means

Error::RefNotFound is raised when a named reference (branch, tag, or explicit `refs/...` path) does not exist in the repository. The lookup started fine (the repo is valid) but the requested ref name resolved to nothing.

Source

Thrown at crates/pi-vcs/src/error.rs:23

//! so the TS layer can match on a structured `kind` instead of message text.

use std::path::PathBuf;

/// Crate-wide result alias.
pub type Result<T, E = Error> = std::result::Result<T, E>;

/// Unified error for all VCS operations.
#[derive(Debug, thiserror::Error)]
pub enum Error {
	/// The directory is not inside a git repository / jj workspace.
	#[error("not a repository: {path}")]
	NotARepository {
		/// Directory the lookup started from.
		path: PathBuf,
	},

	/// A named ref (branch, tag, `refs/...`) does not exist.
	#[error("reference not found: {name}")]
	RefNotFound {
		/// The ref name as given by the caller.
		name: String,
	},

	/// A revision/object lookup failed (`rev-parse` style spec, blob path,
	/// tree).
	#[error("object not found: {spec}")]
	ObjectNotFound {
		/// The revision or object spec as given by the caller.
		spec: String,
	},

	/// Cherry-picking `sha` produced an empty commit (already applied or
	/// auto-resolved to HEAD). Callers should skip and continue the range —
	/// replaces the historical `/the previous cherry-pick is now empty/` stderr
	/// regex.
	#[error("cherry-pick of {sha} is empty")]

View on GitHub (pinned to 9690622007)

Solutions

  1. Run `git branch -a` / `git tag --list` and confirm the exact ref name; fix the typo.
  2. Fetch the missing ref: `git fetch origin <name>` (or fetch with `--tags`).
  3. Use the default branch (main/master) if you assumed a hardcoded branch name.
  4. In code, list refs via the library first and match case-sensitively before resolving.

Example fix

// before
let commit = repo.resolve_ref("origin/master")?; // ref doesn't exist
// after
let name = if repo.ref_exists("origin/master") { "origin/master" } else { "origin/main" };
let commit = repo.resolve_ref(name)?;
Defensive patterns

Strategy: validation

Validate before calling

fn ref_exists(repo: &pi_vcs::Vcs, name: &str) -> bool {
    repo.list_refs().map(|refs| refs.iter().any(|r| r.name == name)).unwrap_or(false)
}
let target = ["origin/main", "origin/master"].into_iter().find(|n| ref_exists(&repo, n))
    .expect("no origin/main or origin/master ref found");

Type guard

fn is_ref_not_found(err: &pi_vcs::Error) -> bool {
    matches!(err, pi_vcs::Error::RefNotFound { .. })
}

Try / catch

match repo.resolve_ref(name) {
    Err(pi_vcs::Error::RefNotFound { name }) => {
        eprintln!("ref `{name}` not found; available: {:?}", repo.list_refs()?.iter().map(|r| &r.name).collect::<Vec<_>>());
    }
    other => other?,
}

Prevention

When it happens

Trigger: APIs resolving refs by name: resolving a branch for a diff/log/commit operation (e.g. `resolve_ref("origin/main")` when the branch is not checked out or not fetched), deleting or reading a tag that was never created, or passing a stale ref name from cached state.

Common situations: Typos in branch/tag names, branch deleted on the remote (stale `origin/feature`), a repo cloned without the tag set (`--depth 1` skips tags), or local-only branches expected to exist after a fresh clone.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/3a4a80085d4ec4d7. Report an issue: GitHub.