GitoxideLabs/gitoxide · error
Invalid pathspec - path must not be empty, not be excluded…
Error message
Invalid pathspec {spec} - path must not be empty, not be excluded, and wildcards are taken literally What it means
Thrown by the repository query engine (`gitoxide_core::query::engine::command::run`) when a pathspec is invalid: the normalized path relative to the repository is empty, or the path is excluded, or it contains wildcards (which are treated literally here). The error includes the offending spec so the user can correct it.
Solutions
- Provide a concrete, non-empty path relative to the repository root instead of `.` or an excluded path
- Remove wildcard characters - paths are matched literally
- Verify the path is not covered by exclusion patterns in the query configuration
- Escape or restructure paths containing `*`, `?`, or `[` characters
Example fix
// before gix repo query --pathspec "src/*.rs" // after # wildcards are literal; list concrete paths instead gix repo query --pathspec "src/main.rs" --pathspec "src/lib.rs"
Defensive patterns
Strategy: validation
Try / catch
if let Err(e) = run(/* args */) {
if e.to_string().starts_with("Invalid pathspec") {
eprintln!("pathspec rejected: {e}");
}
} Prevention
- Reject pathspecs with glob metacharacters at the caller level
- Ensure pathspecs resolve within the repository and are non-empty
When it happens
Trigger: Invoking a query command with a pathspec that (a) normalizes to an empty relative path (e.g. the repo root itself), (b) points to an excluded path (matched by exclusion patterns), or (c) contains glob characters like `*` that this engine does not expand.
Common situations: Passing `.` or the repository root as a path; pathspec matching an ignored/excluded file; using shell-style wildcards like `src/*.rs` expecting glob behavior; scripts constructing pathspecs from variables that end up empty.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- path does not name a file
- Cannot run without any task to perform on the repositories
- At least one operation failed
- No commits to process
- Refusing to checkout index into existing directory
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/a4046f863dfd70d1.
Report an issue: GitHub.
Appendix: source
Thrown at gitoxide-core/src/query/engine/command.rs:32
&self,
cmd: Command,
mut out: impl std::io::Write,
mut progress: impl gix::NestedProgress,
) -> anyhow::Result<()> {
match cmd {
Command::TracePath { spec } => {
let is_excluded = spec.is_excluded();
let relpath = if spec.signature.contains(gix::pathspec::MagicSignature::TOP) {
let root = self.repo.workdir().unwrap_or_else(|| self.repo.git_dir());
let path = root.join(gix::path::from_bstr(spec.path()).as_ref());
self.repo
.normalize_path(gix::path::into_bstr(path).as_ref())?
.into_owned()
} else {
self.repo.normalize_path(spec.path())?.into_owned()
};
if relpath.is_empty() || is_excluded {
bail!(
"Invalid pathspec {spec} - path must not be empty, not be excluded, and wildcards are taken literally"
)
}
let file_id: usize = self
.con
.query_row(
"SELECT file_id FROM files WHERE file_path = ?",
params![relpath.to_str_lossy()],
|r| r.get(0),
)
.optional()?
.with_context(|| format!("Path '{relpath}' not found anywhere in recorded history"))?;
let mut by_file_id = self
.con
.prepare("SELECT hash, mode, source_file_id, has_diff, lines_added, lines_removed from commit_file where file_id = ? order by mode")?;
let mut path_by_id = self.con.prepare("SELECT file_path from files where file_id = ?")?;
let mut seen = HashMap::<usize, String>::new();View on GitHub (pinned to e73179060b)