Egonex-AI/Understand-Anything · warning · BenchmarkArtifactCleanupError

Unable to remove temporary benchmark artifacts

Error message

Unable to remove temporary benchmark artifacts

What it means

BenchmarkArtifactCleanupError is thrown by cleanupBenchmarkArtifacts when rmSync(artifactRoot, { recursive: true, force: true }) raises an exception. force:true already suppresses ENOENT, so a thrown error implies a deeper failure (EBUSY, EPERM, EMFILE, or a path that is not removable). The error is a typed class so callers can distinguish cleanup failures from stage or report errors.

Solutions

  1. Ensure all benchmark stage workers have fully exited before cleanup runs (await their completion).
  2. Retry the removal once after a short delay to let the OS release handles, or re-run with --keep-artifacts and remove manually.
  3. Check permissions on the artifactRoot and its contents; run as a user with delete rights.
  4. On Windows, close any process (antivirus, editor, indexer) that may hold handles inside the temp directory.

Example fix

// before
cleanupBenchmarkArtifacts(artifactRoot);
// after — retry once, then surface a typed error
try { cleanupBenchmarkArtifacts(artifactRoot); }
catch (e) {
  if (e.name !== 'BenchmarkArtifactCleanupError') throw e;
  await new Promise(r => setTimeout(r, 200));
  cleanupBenchmarkArtifacts(artifactRoot);
}
Defensive patterns

Strategy: try-catch

Validate before calling

import { existsSync } from 'node:fs';
if (existsSync(artifactRoot)) { /* safe to attempt cleanup */ } else { /* nothing to do */ }

Type guard

function isCleanupError(e: unknown): boolean {
  return e instanceof Error && e.name === 'BenchmarkArtifactCleanupError';
}

Try / catch

try { cleanupBenchmarkArtifacts(artifactRoot); }
catch (e) {
  if (!isCleanupError(e)) throw e;
  await new Promise(r => setTimeout(r, 200));
  try { cleanupBenchmarkArtifacts(artifactRoot); }
  catch { /* log and continue; artifacts are temporary */ }
}

Prevention

When it happens

Trigger: Removing a temp artifact directory that contains a file held open by another process; insufficient permissions on a file inside artifactRoot; running on Windows where recursive removal hits a locked handle; a path component being a device or special file.

Common situations: Benchmark workers still holding file handles when cleanup runs; antivirus or indexing locking files on Windows; running as a user lacking delete permission; leftover mount points or symlinks inside the artifact tree.

Related errors


AI-assisted analysis of Egonex-AI/Understand-Anything@32944829e7 (2026-08-12). Data as JSON: /api/errors/e20dd31c10248c1d. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/large-repo-benchmark.mjs:124

      backupCleanupFailures: recovery.backupCleanupFailures ?? 0,
      lockReleaseFailures: recovery.lockReleaseFailures ?? 0,
    };
  }
}

export class BenchmarkArtifactCleanupError extends Error {
  constructor() {
    super('Unable to remove temporary benchmark artifacts');
    this.name = 'BenchmarkArtifactCleanupError';
  }
}

export function cleanupBenchmarkArtifacts(artifactRoot, operations = {}) {
  const remove = operations.rmSync ?? rmSync;
  try {
    remove(artifactRoot, { recursive: true, force: true });
  } catch {
    throw new BenchmarkArtifactCleanupError();
  }
}

function takeValue(argv, index, flag) {
  const value = argv[index + 1];
  if (!value || value.startsWith('--')) {
    throw new CliUsageError(`${flag} requires a value`);
  }
  return value;
}

function parseConcurrency(value) {
  return /^[0-9]+$/.test(value) ? Number(value) : Number.NaN;
}

function canonicalizePhysicalPath(pathValue) {
  const lexicalPath = resolve(withoutExtendedWindowsPrefix(pathValue));
  const missingComponents = [];

View on GitHub (pinned to 32944829e7)