affaan-m/ECC · error · Error

artifact not found

Error message

artifact not found: ${file}

What it means

cmdOpen resolves the given file path and checks fs.existsSync before creating a session; if the file does not exist on disk it throws this error, echoing the original (unresolved) path so the user can see what was looked for.

Solutions

  1. Verify the path exists: run `ls -l <file>` (or the absolute equivalent) before invoking open.
  2. Use an absolute path or run from the directory that makes the relative path correct.
  3. Check spelling and case of the filename, especially on Linux.
  4. Regenerate the plan/artifact if it was deleted, and re-run the open command.

Example fix

// before
node scripts/plan-canvas.js open ./.ecc-design/plan.html   # file not there
// after
node scripts/plan-canvas.js open /abs/path/to/project/.ecc-design/plan.html
Defensive patterns

Strategy: validation

Validate before calling

const resolved = path.resolve(file);
if (!fs.existsSync(resolved) || !fs.statSync(resolved).isFile()) {
  console.error(`artifact not found or not a file: ${file}`);
  process.exit(2);
}

Type guard

function isExistingFile(v) {
  try { return typeof v === 'string' && fs.statSync(path.resolve(v)).isFile(); } catch { return false; }
}

Try / catch

try {
  await cmdOpen(file, args, { stateDir, port });
} catch (err) {
  if (err.message.startsWith('artifact not found:')) {
    console.error(`${err.message}\ncwd=${process.cwd()} — use an absolute path or fix the relative path.`);
    process.exit(1);
  }
  throw err;
}

Prevention

When it happens

Trigger: Running `plan-canvas open relative/path.html` from the wrong working directory; a typo in the filename; the plan file deleted or renamed since it was generated; passing a directory path instead of the artifact file.

Common situations: Path built relative to a project root but executed from repo root or /tmp; case-sensitive filesystem mismatches (Plan.HTML vs plan.html); artifacts in a gitignored build dir that a clean removed; symlink targets missing.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at scripts/plan-canvas.js:226

  }
}

function output(payload) {
  process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
}

async function cmdStatus({ stateDir, port }) {
  const health = await healthCheck(port);
  if (!health) {
    return { server: 'not running', hint: 'open an artifact to start one', stateDir };
  }
  const sessions = await request(port, 'GET', '/api/sessions');
  return { server: `http://${DEFAULT_HOST}:${port}`, version: health.version, sessions: sessions.body.sessions };
}

async function cmdOpen(file, args, { stateDir, port }) {
  if (!file) throw new Error('open requires a file path');
  if (!fs.existsSync(path.resolve(file))) throw new Error(`artifact not found: ${file}`);
  await ensureServer({ stateDir, port });
  const res = await request(port, 'POST', '/api/sessions', {
    file: path.resolve(file),
    reopen: args.includes('--reopen')
  });
  if (res.statusCode === 409) return res.body;
  if (res.statusCode !== 200) throw new Error(res.body.error || `open failed (HTTP ${res.statusCode})`);
  const url = `http://${DEFAULT_HOST}:${port}${res.body.url}`;
  const launched = args.includes('--no-open') ? false : openBrowser(url);
  return {
    status: 'open',
    url,
    browser: launched ? 'opened' : 'not opened',
    next_step:
      'Run `ecc-plan-canvas await <file>` and leave it running; it returns when the human sends feedback, a verdict, or ends the session.'
  };
}

View on GitHub (pinned to 8321021c54)