Hmbown/CodeWhale · error

artifact tree exceeds export entry limit

Error message

artifact tree exceeds export entry limit

What it means

The same recursive walk counts every directory entry it visits and aborts once the total exceeds MAX_ARTIFACT_ENTRIES. This bounds export work and archive size when a session's artifacts directory has become enormous or adversarially filled.

Solutions

  1. Prune old or unneeded files from the session's artifacts/ directory and re-export.
  2. Split the session or export only the needed artifact subsets.
  3. Find and stop the process that flooded the artifacts directory.
  4. If the limit is genuinely too small for your workflow, raise MAX_ARTIFACT_ENTRIES explicitly.

Example fix

// before
$ ls artifacts/ | wc -l
50000
// after
$ find artifacts/ -mtime +30 -delete   # prune stale artifacts, then re-export
Defensive patterns

Strategy: validation

Validate before calling

fn entry_count(dir: &Path) -> std::io::Result<u64> {
    let mut n = 0u64;
    for e in walkdir_like(dir) { n += 1; }
    Ok(n)
}
// call before export: assert entry_count(artifacts_dir)? <= MAX_ARTIFACT_ENTRIES;

Prevention

When it happens

Trigger: Exporting a session whose artifacts tree contains more than MAX_ARTIFACT_ENTRIES total files/directories, reached from collect_artifact_files via write_session_archive or recursion.

Common situations: A long-running session accumulated thousands of artifact files; a test runner or tool dumped logs into artifacts/; a runaway process wrote unbounded output under the session's artifacts dir.

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@73e0f67d83 (2026-09-22). 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 73e0f67d83)