affaan-m/ECC · error · Error
ECC_PROJECT_DIR must be an absolute path within /workspace.
Error message
ECC_PROJECT_DIR must be an absolute path within /workspace.
What it means
After successfully parsing frontmatter lines, parseMemoryDocument checks that every key in FRONTMATTER_FIELDS was seen at least once (tracked in a Set of already-parsed object keys). If any required field is absent it throws this error listing the missing field names. This guarantees every memory document is normalized with a complete, known shape before body extraction.
Solutions
- Read the error's field list and add each missing key to the document's frontmatter with a valid value.
- Check for typos in field names — compare against FRONTMATTER_FIELDS in scripts/lib/memory-vault-format.js.
- If migrating old documents, run a one-time script that injects default values for newly required fields.
- Recreate the document via the library's save/normalize API so required fields are always emitted.
Example fix
// before --- title: handoff note --- // after (scope was missing) --- title: handoff note scope: project ---
Defensive patterns
Strategy: validation
Validate before calling
const REQUIRED = ['title', 'scope']; // mirror FRONTMATTER_FIELDS
function frontmatterIsComplete(source) {
const m = /^---\r?\n([\s\S]*?)\r?\n---/.exec(source);
if (!m) return false;
const keys = new Set(m[1].split(/\r?\n/).map(l => l.split(':')[0].trim()).filter(Boolean));
const missing = REQUIRED.filter(k => !keys.has(k));
return missing.length === 0 ? true : missing;
} Type guard
const hasAllFields = (values, required) => required.every(k => Object.prototype.hasOwnProperty.call(values, k) && values[k] != null);
Try / catch
try {
const doc = parseMemoryDocument(source, sourcePath);
} catch (err) {
const m = err.message.match(/missing fields: (.+)\./);
if (m) console.error(`Add frontmatter keys: ${m[1]}`);
else throw err;
} Prevention
- Keep a canonical template containing every FRONTMATTER_FIELDS key and copy it for new documents.
- Keep the required-field list and document templates in sync — update templates whenever FRONTMATTER_FIELDS changes.
- Validate documents in CI before they are committed to the vault.
- Use the library's normalize/save API so required fields are always emitted.
When it happens
Trigger: Calling parseMemoryDocument / memory / parsed with a document whose frontmatter omits one or more required fields (whatever FRONTMATTER_FIELDS declares, e.g. title or scope). Also occurs when a field is misspelled, commented out, or defined only in the body instead of the frontmatter block.
Common situations: Hand-authoring a new memory file and forgetting a required key; renaming a field to a name the schema doesn't recognize; an older document format predating a newly added required FRONTMATTER_FIELDS entry; a template copy where placeholder fields were deleted.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- message
- Cannot adapt Antigravity agent
- Cannot adapt Antigravity agent
- Canonical session snapshot requires aggregates.healths to…
- Canonical session snapshot requires aggregates.states to be…
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/bc6daa1c9e6aa703.
Report an issue: GitHub.
Appendix: source
Thrown at docker/plugin-setup/resolve-project-dir.js:15
#!/usr/bin/env node
'use strict';
const path = require('path');
const WORKSPACE_ROOT = '/workspace';
function resolveProjectDir(candidate) {
if (
typeof candidate !== 'string'
|| !path.posix.isAbsolute(candidate)
|| /[\0\r\n]/.test(candidate)
) {
throw new Error('ECC_PROJECT_DIR must be an absolute path within /workspace.');
}
const resolved = path.posix.resolve(candidate);
if (resolved === WORKSPACE_ROOT || !resolved.startsWith(`${WORKSPACE_ROOT}/`)) {
throw new Error('ECC_PROJECT_DIR must be a child path within /workspace.');
}
return resolved;
}
function main() {
try {
process.stdout.write(`${resolveProjectDir(process.argv[2])}\n`);
} catch (error) {
process.stderr.write(`Error: ${error.message}\n`);
process.exitCode = 2;
}
}
View on GitHub (pinned to 8321021c54)