jdx/mise · error · eyre::Report
cached rustc output directory has unsupported entries
Error message
cached rustc output directory has unsupported entries
What it means
validated_outputs() only accepts flat, version-1 output directories: directory.version must equal 1 and the directories/symlinks lists must be empty (src/cache/rustc.rs:538-541). The rustc adapter caches plain files only, so an entry using a newer format version or containing nested directories/symlinks cannot be safely restored and is rejected. This guard exists to stop a future-format entry from being interpreted with today's semantics.
Source
Thrown at src/cache/rustc.rs:540
Ok(value)
}
fn read_verified_blob(path: &Path, digest: &CacheDigest, description: &str) -> Result<Vec<u8>> {
let mut bytes = Vec::new();
std::fs::File::open(path)?.read_to_end(&mut bytes)?;
if !digest.matches_bytes(&bytes)? {
bail!("cached {description} failed digest verification");
}
Ok(bytes)
}
fn validated_outputs(
directory: CacheDirectory,
outputs: &RustcOutputs,
) -> Result<Vec<(CacheFileNode, PathBuf)>> {
if directory.version != 1 || !directory.directories.is_empty() || !directory.symlinks.is_empty()
{
bail!("cached rustc output directory has unsupported entries");
}
let mut expected = outputs
.files
.iter()
.chain(std::iter::once(&outputs.dep_info))
.map(|path| {
let name = path
.file_name()
.and_then(|name| name.to_str())
.ok_or_else(|| eyre::eyre!("expected rustc output name is not UTF-8"))?;
if path.parent() != Some(outputs.directory.as_path()) {
bail!("expected rustc output escapes its output directory");
}
Ok((name.to_string(), path.clone()))
})
.collect::<Result<BTreeMap<_, _>>>()?;
if directory.files.len() != expected.len() {
bail!("cached rustc output set does not match the invocation");View on GitHub (pinned to 6f52dcdf99)
Solutions
- Upgrade mise to at least the version that wrote the cache entries
- Or purge the cache/namespace so unreadable entries disappear and repopulate with the current version
- Use per-mise-version remote namespaces so format changes never mix (namespace = 'ci-2026-1')
Example fix
# before: one namespace shared across mise versions [settings] task.cache.remote_namespace = 'ci' # after: namespace pinned to the writer's mise version [settings] task.cache.remote_namespace = 'ci-2026-1'
Defensive patterns
Strategy: fallback
Validate before calling
fn supported_cache_directory(d: &CacheDirectory) -> bool {
d.version == 1 && d.directories.is_empty() && d.symlinks.is_empty()
} Prevention
- Pin remote namespace strings to the mise version that writes them
- Upgrade all clients reading a shared cache to at least the writer's version
- Purge caches after downgrades instead of reading newer-format entries
When it happens
Trigger: Restoring an action whose CacheDirectory was written by a newer mise that bumped the version field or started storing directories/symlinks; a remote namespace shared across mise versions where a newer client populated entries your version cannot read.
Common situations: Downgrading mise after a newer version already populated the cache; CI caches written by a refreshed image while an older local mise reads them; mixed-version contributor bases on one shared remote cache.
Related errors
- task cache store version mismatch: local version {}, remote
- invalid remote action manifest ETag
- cached rustc action is missing blob {}
- cache agent returned an incomplete blob lookup response
- cache agent returned an unexpected blob lookup response
AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22).
Data as JSON: /api/errors/dd416b28198541f3.
Report an issue: GitHub.