nikivdev/code · error
{} must be an external CLI source directory or {} file
Error message
{} must be an external CLI source directory or {} file What it means
The fallthrough case of `resolve_install_source_paths`: the given path is neither a directory containing a manifest nor a file named `MANIFEST_NAME`. The library cannot interpret it as an external CLI source and bails.
Source
Thrown at src/external_cli.rs:458
let meta = fs::metadata(path)
.with_context(|| format!("failed to read external CLI source {}", path.display()))?;
if meta.is_dir() {
let manifest_path = path.join(MANIFEST_NAME);
if !manifest_path.is_file() {
bail!("{} does not contain {}", path.display(), MANIFEST_NAME);
}
return Ok((path.to_path_buf(), manifest_path));
}
if meta.is_file() && path.file_name().and_then(|name| name.to_str()) == Some(MANIFEST_NAME) {
let source_root = path
.parent()
.unwrap_or_else(|| Path::new("."))
.to_path_buf();
return Ok((source_root, path.to_path_buf()));
}
bail!(
"{} must be an external CLI source directory or {} file",
path.display(),
MANIFEST_NAME
)
}
fn link_record_path(id: &str) -> PathBuf {
link_records_dir().join(format!("{}.toml", id))
}
fn link_records_dir() -> PathBuf {
config::global_config_dir().join("cli").join("links")
}
fn ensure_link_records_dir() -> Result<PathBuf> {
let dir = link_records_dir();
fs::create_dir_all(&dir).with_context(|| format!("failed to create {}", dir.display()))?;
Ok(dir)View on GitHub (pinned to a747e741ae)
Solutions
- Pass either the tool's source directory or the manifest file itself (named exactly `MANIFEST_NAME`).
- Fix typos in the path.
- Verify the path exists and check its type (`ls -la`).
- If installing from a file, rename it to the expected manifest name or pass its parent directory.
Example fix
// before
installer.install_external_cli_link(Path::new("~/src/my-tool/README.md"))?;
// after
installer.install_external_cli_link(Path::new("~/src/my-tool"))?; Defensive patterns
Strategy: validation
Validate before calling
fn assert_path_is_source(path: &Path, manifest_name: &str) -> Result<(), String> {
match std::fs::metadata(path) {
Ok(m) if m.is_dir() && path.join(manifest_name).is_file() => Ok(()),
Ok(m) if m.is_file() && path.file_name().map_or(false, |n| n == manifest_name) => Ok(()),
_ => Err(format!("{} is not a tool dir or manifest file", path.display())),
}
} Try / catch
match installer.install_external_cli_link(&p) {
Err(e) if e.to_string().contains("must be an external CLI source") => {
eprintln!("{e}; check the path points at a tool directory or manifest");
Err(e)
}
other => other,
} Prevention
- Only pass tool source directories or files named exactly `MANIFEST_NAME`.
- Resolve and print the canonical path before installing to catch typos.
- Never pass arbitrary files (docs, binaries) as install sources.
- Verify path type with `ls -la` or `fs::metadata` first.
When it happens
Trigger: Calling `install_external_cli_link` with a path that is a regular file whose name is not `MANIFEST_NAME`, or a non-directory/non-file entry (device, socket, broken symlink).
Common situations: Passing a README or binary instead of the manifest; passing a path with a typo so it resolves to the wrong file type; pointing at an arbitrary file inside the tool directory instead of the tool directory itself.
Related errors
- {} does not contain {}
- Missing profile: {}
- Source and destination are the same path.
- {} has no exec.run argv in {}
- {} has no exec.run program in {}
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/6cd8f9a0e93c89a6.
Report an issue: GitHub.