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
- Use Capsule.open(dir) instead of create when the capsule may already exist
- Check fs.existsSync(path.join(dir, META_FILE)) (or catch capsule.exists) and branch: open if present, create if not
- Point create at a fresh, unique directory (e.g. run-id-based path) per run
- 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
- Use Capsule.open when a capsule may already exist
- Give each run a fresh, uniquely named directory (timestamp/run-id based)
- Make init scripts idempotent: check-before-create or catch capsule.exists
- Clean up abandoned capsule dirs explicitly before re-initializing
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
- output already exists; choose a new --out
- Receipt output already exists
- all overlays must be readable local files
- all takes must be readable local files
- announcement has a pending receipt; inspect Discord before…
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)