jdx/mise · error
remote cache directory contains duplicate names
Error message
remote cache directory contains duplicate names
What it means
Within a remote directory blob, all child entry names (across directories, files, and symlinks) must be unique. When walking the `directories` list, inserting a name that is already in the names set bails, because a filesystem cannot contain two entries with the same name.
Solutions
- Delete the offending directory blob from the remote store and re-run the task to regenerate it.
- Fix the producer to deduplicate entries by name before serializing the directory blob.
- Validate cached blobs with a script that checks for duplicate names across directories/files/symlinks.
- Avoid hand-editing remote cache blobs.
Example fix
// before: duplicate subdirectory names
{"version":1,"directories":[{"name":"a",...},{"name":"a",...}],...}
// after: unique names
{"version":1,"directories":[{"name":"a",...}],...} Defensive patterns
Strategy: validation
Validate before calling
const names = blob.directories.map(d => d.name);
if (new Set(names).size !== names.length) throw new Error('duplicate directory names'); Prevention
- Deduplicate entries by name before serializing directory blobs.
- Never hand-edit remote cache JSON.
- Lint blobs for duplicate names before upload.
When it happens
Trigger: A remote directory blob lists two subdirectory entries with the same `name` value in its `directories` array.
Common situations: Blobs produced by a buggy or malicious cache writer that doesn't deduplicate entries; hand-edited JSON; corrupted remote data after a bad merge of directory listings.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- invalid remote task cache key
- path must identify an output beneath the task directory
- path must not escape the task directory
- remote cache action keys must use blake3
- remote cache directory graph contains a cycle
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/10c362377247c8c2.
Report an issue: GitHub.
Appendix: 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 533346cc37)