affaan-m/ECC · error · Error
Missing merge payload for uninstall: ${operation.destination
Error message
Missing merge payload for uninstall: ${operation.destinationPath} What it means
During uninstall of a merge-json operation, the installer first tries previousContent / previousJson to restore a backup; if neither is present it must subtract the recorded payload from the current file via deepRemoveJsonSubset. When getOperationJsonPayload returns undefined here, there is no payload to subtract and the uninstall cannot proceed safely.
Source
Thrown at scripts/lib/install-lifecycle.js:742
cleanupTargets: []
};
}
const existingDestination = getContainedExistingPath(
operation.destinationPath,
trustedRoot,
'uninstall'
);
if (!existingDestination) {
return {
removedPaths: [],
cleanupTargets: []
};
}
const payload = getOperationJsonPayload(operation);
if (payload === undefined) {
throw new Error(`Missing merge payload for uninstall: ${operation.destinationPath}`);
}
const currentValue = readJsonNoFollow(
getManagedDestination(existingDestination, trustedRoot, 'uninstall').managedPath
);
const nextValue = deepRemoveJsonSubset(currentValue, payload);
if (nextValue === JSON_REMOVE_SENTINEL) {
const removedPath = removeContainedPath(
operation.destinationPath,
trustedRoot,
'uninstall',
{ force: true }
);
return {
removedPaths: removedPath ? [operation.destinationPath] : [],
cleanupTargets: removedPath ? [removedPath] : []
};
}View on GitHub (pinned to 01e15490f0)
Solutions
- Inspect the merge-json operation in the install-state file and confirm whether `payload`, `previousContent`, or `previousJson` should be present.
- Restore the install-state from a backup or regenerate it by reinstalling over the current target.
- If the target file is user-managed (e.g. ~/.claude/settings.json), manually revert the merged keys and then uninstall.
- Upgrade the installer package to match the version that recorded the operation.
Example fix
// before: uninstall fails — operation has neither payload nor previousContent // after: re-install to repopulate state, then uninstall ./install.sh --target claude ./install.sh --target claude --uninstall
Defensive patterns
Strategy: validation
Validate before calling
function isUninstallableMerge(op) {
if (op.kind !== 'merge-json') return true;
return getOperationPreviousContent(op) !== null
|| getOperationPreviousJson(op) !== undefined
|| getOperationJsonPayload(op) !== undefined;
}
// before uninstall: state.operations.every(isUninstallableMerge) Type guard
function canUninstallMergeOperation(op) {
return op.kind !== 'merge-json' || isUninstallableMerge(op);
} Try / catch
try {
await executeUninstallOperation(op, trustedRoot);
} catch (err) {
if (err.message.startsWith('Missing merge payload for uninstall')) {
// reinstall to populate payload/previousContent, then uninstall
} else throw err;
} Prevention
- Always uninstall with the same installer version that installed.
- Back up merge-target files (settings.json) before uninstall so manual revert is possible.
- Do not strip payload/previousContent fields from install-state.
- Validate the install-state shape before invoking uninstall.
When it happens
Trigger: Uninstall (`./install.sh --uninstall`) of a target whose install-state contains a merge-json operation without a payload and without previousContent/previousJson. Commonly the result of a hand-edited or partially-written state file.
Common situations: State file truncated by a crash mid-write; user manually edited install-state to remove payload fields; version drift where an older installer recorded merge-json without a restorable payload.
Related errors
- Missing merge payload for repair: ${operation.destinationPat
- Unsupported uninstall operation kind: ${operation.kind}
- At least one guided harness must be selected
- ${harness.label} is an advanced harness and is not guided-re
- Target '${target}' is supported, but the bare-language insta
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/eae31c47c1a5393d.
Report an issue: GitHub.