affaan-m/ECC · error · Error

message

Error message

message

What it means

assertMemoryRootSafe looks up roots[scope] and requires it to be a non-empty string path. If the scope key is absent or its value is empty/not a string, the vault cannot know where to store memory for that scope and throws this error naming the scope. This is thrown before any filesystem access occurs.

Solutions

  1. Add the missing scope with a valid absolute directory path to the roots configuration.
  2. Fix the scope name passed to the vault call so it matches a key defined in roots.
  3. Verify the value is a non-empty string, not null/undefined/number.
  4. Synchronize scope constants between caller code and the config file to prevent drift.

Example fix

// before (config)
{ project: '/vault/project' } // no 'personal' scope
resolveMemoryRoot(roots, 'personal');

// after
{ project: '/vault/project', personal: '/vault/personal', [VAULT_ROOT_BOUNDARIES]: { project: '/vault/project', personal: '/vault/personal' } }
Defensive patterns

Strategy: validation

Validate before calling

function assertScopeConfigured(roots, scope) {
  const root = roots?.[scope];
  if (typeof root !== 'string' || root.length === 0) {
    throw new Error(`Scope "${scope}" has no memory root configured. Add it to your roots config.`);
  }
}

Type guard

const hasScopeRoot = (roots, scope) => typeof roots?.[scope] === 'string' && roots[scope].length > 0;

Try / catch

try {
  const root = resolveMemoryRoot(roots, scope);
} catch (err) {
  if (err.message.startsWith('No memory root is configured')) {
    throw new Error(`Unknown memory scope "${scope}". Configured scopes: ${Object.keys(roots).filter(k => k !== '__boundaries').join(', ')}`);
  }
  throw err;
}

Prevention

When it happens

Trigger: Requesting a scope (e.g. 'personal', 'project') that is not present in the roots config object, or whose value is '' or a non-string (number, null). Also occurs when the config defines the scope under a differently-cased or misspelled key.

Common situations: Typos in the scope name at the call site ('Project' vs 'project'); a fresh install where the config template only defines some scopes; an environment-specific config that omits a scope; a renamed scope constant not updated everywhere.

Related errors


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

Appendix: source

Thrown at docker/plugin-setup/verify-install-plan.js:9

#!/usr/bin/env node

'use strict';

const fs = require('fs');
const path = require('path');

function fail(message) {
  throw new Error(message);
}

function isWithin(root, candidate) {
  const relative = path.relative(root, candidate);
  return relative === '' || (
    relative !== '..'
    && !relative.startsWith(`..${path.sep}`)
    && !path.isAbsolute(relative)
  );
}

function validatePlan(payload, projectDir, requireDryRun) {
  const expectedRoot = path.resolve(projectDir, '.claude');
  if (!payload || typeof payload !== 'object' || !payload.plan) {
    fail('Install output is missing a plan.');
  }
  if (requireDryRun && payload.dryRun !== true) {
    fail('Install plan did not report dryRun=true.');

View on GitHub (pinned to 8321021c54)