jdx/mise · error
remote cache directory contains duplicate names
Error message
remote cache directory contains duplicate names
What it means
Inside each fetched directory proto, mise collects entry names into one BTreeSet shared across the directories, files, and symlinks lists. A name repeated within the directories list - or colliding with a name already seen - bails with 'remote cache directory contains duplicate names' during restore.
Source
Thrown at src/task/task_cache_store.rs:729
let mut pending = vec![(PathBuf::new(), root.clone(), BTreeSet::new())];
let mut nodes = BTreeMap::<PathBuf, RestoredNode>::new();
while let Some((path, digest, mut ancestors)) = pending.pop() {
if !ancestors.insert(digest.clone()) {
bail!("remote cache directory graph contains a cycle");
}
let bytes = store.client.get_blob(&digest, DIRECTORY_MEDIA_TYPE).await?;
let directory: RemoteDirectory = serde_json::from_slice(&bytes)?;
if canonical_json(&serde_json::to_value(&directory)?)? != bytes {
bail!("remote cache directory is not canonical JSON");
}
if directory.version != 1 {
bail!("unsupported remote cache directory version");
}
let mut names = BTreeSet::new();
for directory in directory.directories {
validate_cache_name(&directory.name)?;
if !names.insert(directory.name.clone()) {
bail!("remote cache directory contains duplicate names");
}
let child = path.join(&directory.name);
validate_cache_path(&child)?;
nodes.insert(
child.clone(),
RestoredNode::Directory {
mode: directory.mode,
},
);
pending.push((child, directory.digest, ancestors.clone()));
}
for file in directory.files {
validate_cache_name(&file.name)?;
if !names.insert(file.name.clone()) {
bail!("remote cache directory contains duplicate names");
}
let child = path.join(&file.name);
validate_cache_path(&child)?;View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Purge the entry from the remote cache and re-run the task
- Ensure a single-writer mise version across the team
- Inspect the directory blob at the failing digest and fix or delete it
Example fix
// directory proto
// before
"directories": [{"name": "out"}, {"name": "out"}]
// after
"directories": [{"name": "out"}] Defensive patterns
Strategy: fallback
Validate before calling
// when generating protos, enforce unique names before upload:
let mut names = std::collections::BTreeSet::new();
for d in &proto.directories {
if !names.insert(d.name.clone()) {
return Err(eyre::bail!("duplicate directory name {}", d.name));
}
} Type guard
fn directory_names_unique(directories: &[RemoteDirectoryNode]) -> bool {
let mut names = std::collections::BTreeSet::new();
directories.iter().all(|d| names.insert(d.name.clone()))
} Try / catch
match materialize_remote_tree(&store, &root).await {
Ok(tree) => tree,
Err(err) if err.to_string().contains("duplicate names") => {
warn!("corrupt directory proto at digest; purging entry");
purge_action_result(&key).await.ok();
run_task_uncached(&task).await?
}
Err(err) => return Err(err),
} Prevention
- Generate directory protos with sorted, deduplicated name lists
- Validate uniqueness server-side if you accept proto uploads
- Treat duplicate-name errors as corruption: purge and rebuild, do not hand-patch blobs in place
When it happens
Trigger: materialize_remote_tree processes a directory blob whose directories array lists the same name twice (or reuses a name inserted earlier while iterating the entries).
Common situations: Corrupt or hand-merged blobs; non-mise writers producing protos; a server serving a mismatched blob for a digest.
Related errors
- remote action result is missing its output root
- remote cache directory graph contains a cycle
- remote cache directory is not canonical JSON
- unsupported remote cache client metadata version
- remote cache metadata kind is not a task
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/10c362377247c8c2.
Report an issue: GitHub.