affaan-m/ECC · error · Error

A managed install-state path is required before preflight.

Error message

A managed install-state path is required before preflight.

What it means

preflightManagedPlan requires plan.installStatePath to be a non-empty string because the preflight step must read and compare an install-state file before applying operations. An empty or missing installStatePath means the plan cannot safely checkpoint state, so it throws before touching disk.

Solutions

  1. Ensure the plan is built by createMultiHarnessPlan/applyMultiHarnessPlan which set installStatePath
  2. If building manually, set plan.installStatePath to a valid file path before preflight
  3. Check for empty-string paths coming from config/env interpolation

Example fix

// before
const plan = { operations: [...] };
// after
const plan = { operations: [...], installStatePath: '.ecc/install-state.json' };
Defensive patterns

Strategy: validation

Validate before calling

if (typeof plan?.installStatePath !== 'string' || plan.installStatePath.length === 0) {
  throw new Error('plan.installStatePath must be a non-empty string');
}

Type guard

function hasInstallStatePath(p) {
  return typeof p?.installStatePath === 'string' && p.installStatePath.length > 0;
}

Try / catch

try {
  await preflight(plan);
} catch (e) {
  if (e.message.includes('install-state path is required')) {
    plan = await createMultiHarnessPlan(request); // rebuild with proper state path
  } else throw e;
}

Prevention

When it happens

Trigger: Constructing a plan manually or mutating it so installStatePath is undefined/null/empty; a plan built by an older code path that didn't set installStatePath; a serialized plan that dropped the field.

Common situations: Custom tooling around multi-harness-setup building plans by hand; tests instantiating plan fixtures without installStatePath; upgrading plans created by a previous version of the script.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at scripts/lib/multi-harness-setup.js:348

  for (const [candidatePath, mode] of requirements) {
    try {
      accessSync(candidatePath, mode);
    } catch (_error) {
      const label = plan.target === 'kimi' ? 'Kimi' : 'Managed install';
      throw new Error(
        `${label} destination is not writable by the current user: ${candidatePath}. `
        + 'Fix the project ownership or permissions, then retry.'
      );
    }
  }
}

function preflightManagedPlan(plan, dependencies = {}) {
  if (!plan || !Array.isArray(plan.operations)) {
    throw new Error('A managed install plan with operations is required.');
  }
  if (typeof plan.installStatePath !== 'string' || plan.installStatePath.length === 0) {
    throw new Error('A managed install-state path is required before preflight.');
  }
  const ownership = readOwnedDestinations(plan, dependencies);
  const operations = plan.operations.map(operation => {
    assertSafeInstallOperation(plan, operation);
    return {
      destinationPath: operation.destinationPath,
      kind: operation.kind,
      classification: classifyManagedOperation(operation, ownership.destinations),
    };
  });
  assertManagedDestinationsWritable(plan, dependencies);
  return {
    plan,
    operations,
    ownershipSnapshot: {
      destinations: [...ownership.destinations],
      stateFingerprint: ownership.stateFingerprint,
    },

View on GitHub (pinned to 8321021c54)