affaan-m/ECC · error · CapsuleError

capsule.exists

capsule.exists

Error message

capsule already exists at ${resolved}

What it means

Capsule.create refuses to initialize a capsule in a directory that already contains a meta file (capsule.exists). Capsule metadata is intended to be written once; re-running create over the same directory would silently reset sequence numbers and hashes, corrupting the hash-linked journal chain. The resolved path is included in the message.

Solutions

  1. Use Capsule.open(dir) instead of create when the capsule may already exist
  2. Check fs.existsSync(path.join(dir, META_FILE)) (or catch capsule.exists) and branch: open if present, create if not
  3. Point create at a fresh, unique directory (e.g. run-id-based path) per run
  4. If the old capsule is truly disposable and you intend to discard it, explicitly delete the directory first, then create

Example fix

// before
const capsule = Capsule.create('./out');
// after
let capsule;
try {
  capsule = Capsule.open('./out');
} catch (e) {
  if (e.code === 'capsule.file_not_found' || e.code === 'capsule.directory_not_found') {
    capsule = Capsule.create('./out');
  } else throw e;
}
Defensive patterns

Strategy: validation

Validate before calling

const path = require('path');
const fs = require('fs');
function canCreateCapsule(dir) {
  const resolved = path.resolve(dir);
  return !fs.existsSync(path.join(resolved, 'meta.json'));
}

Try / catch

let capsule;
try {
  capsule = Capsule.create(dir);
} catch (e) {
  if (e.code === 'capsule.exists') capsule = Capsule.open(dir);
  else throw e;
}

Prevention

When it happens

Trigger: Calling Capsule.create(dir) where dir already contains META_FILE; re-running a setup script twice; pointing create at an existing capsule directory instead of Capsule.open(dir); a previous run partially succeeded and left the meta file in place.

Common situations: Re-running an eval pipeline without cleaning its output dir; idempotency scripts that call create on every start; mixing 'create new capsule' and 'resume existing capsule' logic in one code path; copying a capsule directory and re-initializing it.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/f3dbc7639cdd94dd. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/eval-harness/capsule.js:141

class Capsule {
  /**
   * @param {string} dir capsule root (created if missing)
   * @param {object} meta { run_id, capsule_id, harness_version, task_family }
   */
  constructor(dir, meta, options = {}) {
    this.dir = path.resolve(dir);
    this.meta = meta;
    this.clock = options.clock || null;
    this.journalPath = path.join(this.dir, JOURNAL_FILE);
    this.lastHash = envelope.GENESIS_HASH;
    this.nextSeq = 0;
  }

  static create(dir, options = {}) {
    const resolved = path.resolve(dir);
    if (fs.existsSync(path.join(resolved, META_FILE))) {
      throw new CapsuleError('capsule.exists', `capsule already exists at ${resolved}`);
    }
    const meta = {
      schema: envelope.SCHEMA_VERSION,
      run_id: options.run_id === undefined ? newId('run') : options.run_id,
      capsule_id: options.capsule_id === undefined ? newId('capsule') : options.capsule_id,
      harness_version: options.harness_version === undefined ? 'unknown' : options.harness_version,
      task_family: options.task_family === undefined ? 'unspecified' : options.task_family,
      created_at: nowIso(options.clock),
    };
    const failure = metadataFailure(meta);
    if (failure) throw new CapsuleError(failure.code, failure.reason);
    fs.mkdirSync(resolved, { recursive: true });
    fs.writeFileSync(path.join(resolved, META_FILE), canonicalJson(meta) + '\n', 'utf8');
    fs.writeFileSync(path.join(resolved, JOURNAL_FILE), '', 'utf8');
    return new Capsule(resolved, meta, options);
  }

  static open(dir, options = {}) {

View on GitHub (pinned to 8321021c54)