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
- Use the fully qualified form: `owner/repo` instead of the bare name
- Clone first: `f repos clone <url>`, then retry with the local name
- List what is actually under the printed root to find the correct name
- 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
- Always use owner/repo form in scripts and aliases
- Clone via `f repos clone <url>` so names resolve locally
- Periodically list the repos root to keep names known
- Watch for moved/changed repos root in config
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
- multiple matches for '{}': {}. Use owner/repo.
- Missing profile: {}
- Could not find agent file for '{}'
- No prompt provided. Usage: f agents run {} "your prompt here
- connect is only supported for Codex sessions; use `f codex c
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/2aa1dbbfa237ab1c.
Report an issue: GitHub.