nikivdev/code · error · anyhow::Error

repo '{}' not found under {}. Use owner/repo or run: f repos

Error message

repo '{}' not found under {}. Use owner/repo or run: f repos clone <url>

What it means

Raised when resolving a short repo `name` against locally cloned repos under the repos root (src/deps.rs:1321) finds zero matches. The tool requires either an `owner/repo` qualifier or a prior local clone; it refuses to guess. The message tells you the root it searched and the two remedies.

Source

Thrown at src/deps.rs:1321

    let root_entries =
        std::fs::read_dir(root).with_context(|| format!("failed to read {}", root.display()))?;

    for owner_entry in root_entries.flatten() {
        if !owner_entry.file_type().map(|t| t.is_dir()).unwrap_or(false) {
            continue;
        }
        let owner = owner_entry.file_name().to_string_lossy().to_string();
        let repo_path = owner_entry.path().join(name);
        if repo_path.is_dir() {
            matches.push(repos::RepoRef {
                owner,
                repo: name.to_string(),
            });
        }
    }

    if matches.is_empty() {
        bail!(
            "repo '{}' not found under {}. Use owner/repo or run: f repos clone <url>",
            name,
            root.display()
        );
    }

    if matches.len() > 1 {
        let options = matches
            .iter()
            .map(|repo| format!("{}/{}", repo.owner, repo.repo))
            .collect::<Vec<_>>()
            .join(", ");
        bail!(
            "multiple matches for '{}': {}. Use owner/repo.",
            name,
            options
        );
    }

View on GitHub (pinned to a747e741ae)

Solutions

  1. Use the fully qualified form: `owner/repo` instead of the bare name
  2. Clone first: `f repos clone <url>`, then retry with the local name
  3. List what is actually under the printed root to find the correct name
  4. Check config for a changed repos root path

Example fix

// before
f deps open foo
error: repo 'foo' not found under ~/.f/repos ...
// after
f repos clone https://github.com/acme/foo.git
f deps open acme/foo
Defensive patterns

Strategy: validation

Validate before calling

let repos_root = Path::new("~/.f/repos");
let short = name.rsplit('/').next().unwrap();
let exists = std::fs::read_dir(repos_root)
    .map(|rd| rd.filter_map(|e| e.ok())
        .any(|e| e.file_name().to_string_lossy() == short))
    .unwrap_or(false);
if !exists && !name.contains('/') {
    anyhow::bail!("clone first or use owner/repo form for '{name}'");
}

Type guard

fn is_qualified_repo(name: &str) -> bool {
    let parts: Vec<&str> = name.split('/').collect();
    parts.len() == 2 && parts.iter().all(|p| !p.is_empty())
}

Try / catch

match resolve_repo(name) {
    Err(e) if e.to_string().contains("not found under") => {
        eprintln!("{e:#}");
        eprintln!("hint: f repos clone <url>, then use owner/repo");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Passing a bare name (e.g. `foo`) to a repo-targeting command when no directory under the repos root matches that name — the repo was never cloned, was cloned under a different name, or lives under a different root directory.

Common situations: Typos in the repo name, cloning with a URL that produced a different directory name, a moved/changed repos root in config, or expecting the tool to fetch remote repos it has never cloned locally.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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