Hmbown/CodeWhale · error · io::Error (InvalidData)

artifact tree exceeds export entry limit

Error message

artifact tree exceeds export entry limit

What it means

The artifact walk counts every directory entry it visits and enforces MAX_ARTIFACT_ENTRIES across the whole tree. Exceeding the cap aborts the export with InvalidData, protecting the exporter from huge artifact trees that would blow up archive size, memory, and time.

Solutions

  1. Prune or clean the artifacts directory, keeping only meaningful files.
  2. Aggregate many small files into one archive/bundle before placing them in artifacts.
  3. Raise MAX_ARTIFACT_ENTRIES if the volume is legitimate, accepting a larger export.
  4. Count entries first (`find <dir> | wc -l`) to see what is bloating the tree.

Example fix

// before
// artifacts/logs/ contains 100,000 frame dumps -> export fails
// after: keep only the summary
for f in glob("<artifacts>/logs/frame-*.png") { fs::remove_file(f)?; }
write_session_archive(&session, dir, &out, options)?;
Defensive patterns

Strategy: validation

Validate before calling

fn count_entries(dir: &Path) -> usize {
    fn walk(d: &Path, n: &mut usize) {
        if let Ok(rd) = std::fs::read_dir(d) {
            for e in rd.flatten() { *n += 1; if e.file_type().map(|t| t.is_dir()).unwrap_or(false) { walk(&e.path(), n); } }
        }
    }
    let mut n = 0; walk(dir, &mut n); n
}
// if count_entries(artifacts) > MAX_ARTIFACT_ENTRIES { prune first }

Try / catch

match write_session_archive(&session, dir, out, opts) {
    Err(e) if e.to_string().contains("entry limit") => {
        eprintln!("too many artifact files; clean the artifacts directory");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Exporting a session whose artifacts directory (recursively) contains more entries than MAX_ARTIFACT_ENTRIES — e.g. thousands of log files, cache fragments, or an extracted node_modules tree left in the artifacts folder.

Common situations: Long-running sessions that accumulate per-step logs; tools that drop per-frame or per-test artifacts; accidentally pointing the artifacts dir at a broad cache directory.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/56c2fca2c2cbdd35. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/session_export.rs:348

fn collect_artifact_files_recursive(
    sessions_dir: &Path,
    dir: &Path,
    prefix: &str,
    depth: usize,
    entries: &mut usize,
    files: &mut Vec<(String, PathBuf)>,
) -> io::Result<()> {
    if depth > MAX_ARTIFACT_DEPTH {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            "artifact tree exceeds export depth limit",
        ));
    }
    for entry in fs::read_dir(dir)? {
        let entry = entry?;
        *entries += 1;
        if *entries > MAX_ARTIFACT_ENTRIES {
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                "artifact tree exceeds export entry limit",
            ));
        }
        let file_type = entry.file_type()?;
        if file_type.is_symlink() {
            continue;
        }
        let child = entry.file_name();
        let child = child
            .to_str()
            .filter(|name| !name.contains(['\\', ':']))
            .ok_or_else(|| {
                io::Error::new(
                    io::ErrorKind::InvalidData,
                    "artifact name is not portable UTF-8",
                )
            })?;

View on GitHub (pinned to 433685b202)