GitoxideLabs/gitoxide · error · anyhow::Error
Adding files requires a worktree directory that contains…
Error message
Adding files requires a worktree directory that contains them
What it means
Thrown by `stream` in gitoxide-core's archive command when `--add` paths were supplied but the repository is bare (no worktree). Adding files to the archive stream requires resolving paths against a real working directory via `repo.workdir()`, which is `None` for bare repositories.
Solutions
- Run the command in a non-bare clone that has a working tree
- Drop the `--add` flags and only stream from a tree/commit, which does not need a workdir
- Convert the bare repo: `git worktree add <dir> <ref>` and run against the worktree, or `git clone` a normal checkout
Example fix
// before (bare repo) gix repo archive HEAD --add extra.txt // after gix repo archive HEAD # stream tree contents only, no --add
Defensive patterns
Strategy: validation
Validate before calling
if add_paths.is_empty() {
// safe: no workdir needed
} else if repo.workdir().is_none() {
return Err("--add requires a non-bare repository with a worktree".into());
} Type guard
fn supports_add_paths(repo: &gix::Repository) -> bool {
repo.workdir().is_some()
} Prevention
- Check `git rev-parse --is-bare-repository` before combining archive/merge commands with worktree-dependent flags
- Only use `--add` in full checkouts
When it happens
Trigger: Calling `gix archive ... --add <path>` (via `stream`) inside or against a bare repository, or a repository opened with `--bare`/`open::Kind::Bare` so `repo.workdir()` returns `None`.
Common situations: Running the archive command on a server-side bare clone that only exists for hosting; CI checkout configured as bare to save space.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- repository at must have a worktree checkout
- Need a worktree to clean, this is a bare repository
- `--update-head` cannot be used with `--in-memory` - cannot…
- `--update-head` requires `--message`
- Only 'human' format is currently supported
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/d8f18303b85ba1bd.
Report an issue: GitHub.
Appendix: source
Thrown at gitoxide-core/src/repository/archive.rs:34
rev_spec: Option<&str>,
mut progress: impl NestedProgress,
Options {
format,
prefix,
add_paths,
files,
}: Options,
) -> anyhow::Result<()> {
let format = format.map_or_else(|| format_from_ext(destination_path), Ok)?;
let object = repo.rev_parse_single(rev_spec.unwrap_or("HEAD"))?.object()?;
let (modification_date, tree) = fetch_rev_info(object)?;
let start = std::time::Instant::now();
let (mut stream, index) = repo.worktree_stream(tree)?;
if !add_paths.is_empty() {
let root = gix::path::realpath(
repo.workdir()
.ok_or_else(|| anyhow!("Adding files requires a worktree directory that contains them"))?,
)?;
for path in add_paths {
stream.add_entry_from_path(&root, &gix::path::realpath(&path)?, repo.object_hash())?;
}
}
for (path, content) in files {
stream.add_entry(gix::worktree::stream::AdditionalEntry {
id: gix::hash::Kind::Sha1.null(),
mode: gix::object::tree::EntryKind::Blob.into(),
relative_path: path.into(),
source: gix::worktree::stream::entry::Source::Memory(content.into()),
});
}
let mut entries = progress.add_child("entries");
entries.init(Some(index.entries().len()), gix::progress::count("entries"));
let mut bytes = progress.add_child("written");
bytes.init(None, gix::progress::bytes());View on GitHub (pinned to e73179060b)