affaan-m/ECC · error · Error
Refusing to ${action}: missing destination path.
Error message
Refusing to ${action}: missing destination path. What it means
Every managed write/delete in the install lifecycle goes through getManagedDestination(), which requires a non-empty string destinationPath before touching the filesystem. This is the first, cheapest guard: refuse the action (copy, write, remove, uninstall, repair) when the destination is missing, undefined, or not a string.
Source
Thrown at scripts/lib/install-lifecycle.js:292
return parseJsonLikeValue(operation[key], `${operation.kind}.${key}`);
}
}
return undefined;
}
function formatJson(value) {
return `${JSON.stringify(value, null, 2)}\n`;
}
function getManagedDestination(
destinationPath,
trustedRoot,
action,
{ allowFinalSymlink = false } = {}
) {
if (!destinationPath || typeof destinationPath !== 'string') {
throw new Error(`Refusing to ${action}: missing destination path.`);
}
const canonicalRoot = assertWithinTrustedRoot(trustedRoot, trustedRoot, action);
const resolvedDestination = path.resolve(destinationPath);
const canonicalParent = assertWithinTrustedRoot(
path.dirname(resolvedDestination),
canonicalRoot,
action
);
const managedPath = path.join(canonicalParent, path.basename(resolvedDestination));
let stat = null;
try {
stat = fs.lstatSync(managedPath);
} catch (error) {
if (!error || (error.code !== 'ENOENT' && error.code !== 'ENOTDIR')) {
throw error;
}View on GitHub (pinned to d8409a4b08)
Solutions
- Inspect the operation being executed at failure time and add the missing destinationPath
- Discard the mutated state and re-run a fresh ./install.sh so state is regenerated from current manifests
- If you call the lifecycle APIs directly, assert typeof destinationPath === 'string' && destinationPath before invoking
Defensive patterns
Strategy: validation
Validate before calling
function assertDestinationPath(operation) {
if (!operation.destinationPath || typeof operation.destinationPath !== 'string') {
throw new Error(`operation ${operation.kind} is missing destinationPath — regenerate install state`);
}
} Type guard
function hasDestinationPath(operation) {
return typeof operation?.destinationPath === 'string' && operation.destinationPath.length > 0;
} Try / catch
try {
writeContainedFile(op.destinationPath, content, root, 'repair');
} catch (err) {
if (/missing destination path/.test(err.message)) {
// state corruption: re-run a full install instead of patching operations
}
throw err;
} Prevention
- Never hand-edit install-state; regenerate it with a fresh install
- Validate the whole operations[] array (destinationPath present and string) immediately after loading state
- Treat state files as machine-owned artifacts and keep backups before experimenting
When it happens
Trigger: An install-state operations[] entry with no destinationPath; calling writeContainedFile/removeContainedPath/getManagedDestination with an undefined first argument; a corrupted or truncated state file.
Common situations: Hand-editing the ECC install-state JSON and dropping a field; state written by an incompatible (older/newer) schema; programmatic callers that assume a default destination.
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
- Nasiko install directory must be an absolute path.
- Nasiko cannot install directly into a filesystem root.
- Unable to infer ECC repo root from install-state operations
- Invalid ECC repo root: missing package.json at ${packageJson
- Invalid ECC repo root: missing install script at ${installAp
AI-assisted analysis of affaan-m/ECC@d8409a4b08 (2026-08-26).
Data as JSON: /api/errors/2dbed32ec08d7be5.
Report an issue: GitHub.