affaan-m/ECC · error · Error
A managed install plan with operations is required.
Error message
A managed install plan with operations is required.
What it means
preflightManagedPlan validates that the caller passed a real managed install plan containing an operations array before doing any work. If plan is null/undefined or plan.operations is not an array, it throws immediately. This is a guard against callers (preview/result/latestPreview) passing an un-built or corrupt plan object.
Solutions
- Create the plan via createMultiHarnessPlan() before calling preview/result
- Inspect the plan object: it must have a non-empty operations array
- If a plan was persisted/serialized, persist and restore operations too
Example fix
// before await preview(null); // after const plan = await createMultiHarnessPlan(request); await preview(plan);
Defensive patterns
Strategy: type-guard
Validate before calling
if (!plan || !Array.isArray(plan.operations) || plan.operations.length === 0) {
throw new Error('caller bug: plan has no operations');
} Type guard
function isManagedPlan(p) {
return Boolean(p) && Array.isArray(p.operations) && typeof p.installStatePath === 'string' && p.installStatePath.length > 0;
} Try / catch
try {
await preview(plan);
} catch (e) {
if (e.message.includes('managed install plan with operations')) {
plan = await createMultiHarnessPlan(request); // rebuild and retry once
} else throw e;
} Prevention
- Always obtain plans from createMultiHarnessPlan, never hand-build them
- Don't partially destructure/reassign plan objects
- Validate plans with a guard after deserialization
When it happens
Trigger: Calling preview(), result(), or latestPreview() with no plan, a plan object that never went through createMultiHarnessPlan, or a plan whose operations field was reassigned or serialized away (e.g. lost as JSON without operations).
Common situations: Passing the output of a failed/aborted plan build; destructuring or transforming a plan and dropping the operations field; calling preview with null on an early-return code path.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- -32602
- a claim token is required
- a confirmed nonempty coordinate is required
- a generated candidate cannot claim original-source identity
- A managed install-state path is required before preflight.
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/e910af82bc98bbbc.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/multi-harness-setup.js:345
requirements.set(requirement.candidatePath, existingMode | requirement.mode);
}
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: {View on GitHub (pinned to 8321021c54)