affaan-m/ECC · error · Error
Project memory .gitignore does not contain the required…
Error message
Project memory .gitignore does not contain the required fail-closed rules.
What it means
ensureProjectScopeIgnored verifies that the project memory directory's .gitignore exactly matches the library's required fail-closed content (PROJECT_MEMORY_GITIGNORE). If a pre-existing .gitignore differs at all, it throws this error rather than silently overwriting user content. This guarantees project-scope memories are never committed to git.
Solutions
- Delete the existing .gitignore in the project memory directory so the library recreates it with the required rules.
- Or replace its content with the exact canonical PROJECT_MEMORY_GITIGNORE text.
- Check git history of the vault to see what changed and restore the canonical content.
Example fix
// before (edited .gitignore) # my notes * // after cat scripts/lib/memory-vault.js | grep -A5 PROJECT_MEMORY_GITIGNORE # copy exact content into the vault .gitignore, or: rm <vault>/project/.gitignore
Defensive patterns
Strategy: validation
Validate before calling
const expected = PROJECT_MEMORY_GITIGNORE; // canonical content from the library const current = fs.readFileSync(path.join(vaultProjectDir, '.gitignore'), 'utf8'); if (current !== expected) fs.writeFileSync(path.join(vaultProjectDir, '.gitignore'), expected);
Try / catch
try {
saveMemory(memory);
} catch (err) {
if (err.message.includes('fail-closed rules')) {
// restore canonical .gitignore, then retry the save
} else throw err;
} Prevention
- Never hand-edit .gitignore files inside the memory vault.
- After upgrading the library, let it recreate vault config files.
- Treat the vault directory as library-managed; modify only via APIs.
- Add a CI check comparing vault .gitignore to the canonical constant if the vault is shared.
When it happens
Trigger: Calling saveMemory or directories for a project-scoped memory when a .gitignore already exists in the project memory directory but its content differs from the canonical PROJECT_MEMORY_GITIGNORE string.
Common situations: A user or tool manually edited the vault .gitignore (added comments, different rules); an older library version wrote a different .gitignore format and the library was upgraded; a formatter normalized the file (trailing newline changes).
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- has too many values (maximum ).
- is too long (maximum characters).
- must be a lowercase letters/numbers slug.
- must be a non-empty string.
- must be an array.
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/34647dcb4dbbbd16.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/memory-vault.js:257
if (operationError) throw operationError;
if (cleanupError) throw cleanupError;
}
function ensureProjectScopeIgnored(roots, scope) {
if (scope !== 'project') return;
const root = roots.project;
const ignorePath = path.join(root, '.gitignore');
try {
writeCreateOnlyTextFile(ignorePath, PROJECT_MEMORY_GITIGNORE, root);
} catch (error) {
if (!error || error.code !== 'EEXIST') throw error;
const existing = readRegularTextFile(ignorePath, {
label: 'project memory .gitignore',
maxBytes: MAX_DOCUMENT_BYTES,
trustedRoot: root,
});
if (existing !== PROJECT_MEMORY_GITIGNORE) {
throw new Error(
'Project memory .gitignore does not contain the required fail-closed rules.'
);
}
}
}
function normalizeScopes(scopes = MEMORY_SCOPES) {
const values = Array.isArray(scopes) ? scopes : [scopes];
return uniqueStrings(values, {
label: 'scopes',
limit: MEMORY_SCOPES.length,
validator: value => validateEnum(value, MEMORY_SCOPES, 'memory scope'),
});
}
function initializeVault(options = {}) {
const roots = options.roots || resolveVaultRoots(options);
const scopes = normalizeScopes(options.scopes || DEFAULT_RECALL_SCOPES);View on GitHub (pinned to 8321021c54)