affaan-m/ECC · error · Error
--legacy-codex-sync cannot be combined with --target
Error message
--legacy-codex-sync cannot be combined with --target
What it means
The uninstall script enforces that --legacy-codex-sync (a full legacy-state sync mode) and --target (selective component removal) are mutually exclusive operation modes. Throwing here prevents an ambiguous uninstall where the script could not decide whether to sync everything or remove only selected targets.
Solutions
- Remove either --legacy-codex-sync or all --target flags from the command — run one mode at a time
- If you want selective removal, drop --legacy-codex-sync and list only the targets
- If you want a full legacy sync, drop all --target flags
- Check the script's help output (it runs showHelp on bad input paths) for current flag combinations
Example fix
// before node scripts/uninstall.js --legacy-codex-sync --target commands // after node scripts/uninstall.js --target commands
Defensive patterns
Strategy: validation
Validate before calling
const args = process.argv.slice(2);
if (args.includes('--legacy-codex-sync') && (args.includes('--target') || args.includes('--targets'))) {
throw new Error('--legacy-codex-sync cannot be combined with --target');
} Type guard
function isExclusiveCombo(options) {
return typeof options.legacyCodexSync === 'boolean' &&
Array.isArray(options.targets) &&
options.targets.length > 0 &&
options.legacyCodexSync === true;
} Try / catch
try {
await main(process.argv.slice(2));
} catch (err) {
if (err.message.includes('cannot be combined')) {
console.error('Pick either --legacy-codex-sync OR --target flags, not both.');
process.exit(2);
}
throw err;
} Prevention
- Run one uninstall mode per invocation; chain separate commands if both are needed
- Keep flag recipes in scripts updated when migrating away from legacy workflows
- Add a shell alias per mode instead of accumulating flags
- Check --help before combining unfamiliar flags
When it happens
Trigger: Running `node scripts/uninstall.js --legacy-codex-sync --target <name>` (or any --targets value) so that options.legacyCodexSync is truthy while options.targets.length > 0 when main() validates the parsed options.
Common situations: Users upgrading from older install workflows combine a remembered --legacy-codex-sync flag with newer --target flags copied from docs or shell history; shell aliases or CI scripts accumulating flags from different eras of the tool.
Understand the failure class
Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.
Related errors
- Choose only one output format: --json or --markdown
- Choose exactly one memory body source: --stdin or…
- --enable-hooks and --no-hooks are mutually exclusive
- graph sync does not accept a session ID when --all is set
- Agents directory not found
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/9b24bea9f6a78deb.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/uninstall.js:150
}
return options.dryRun || dryRunEnv === '1';
}
function includesCodexTarget(targets) {
return targets.length === 0 || targets.includes('codex');
}
async function main() {
try {
const options = parseArgs(process.argv);
if (options.help) {
showHelp(0);
}
const dryRun = isDryRun(options);
if (options.legacyCodexSync && options.targets.length > 0) {
throw new Error('--legacy-codex-sync cannot be combined with --target');
}
let result;
let mode = 'install-state';
if (options.legacyCodexSync) {
result = uninstallLegacyCodexSync({
codexHome: codexHomePath(),
dryRun,
});
mode = 'legacy-codex-sync';
} else {
result = uninstallInstalledStates({
homeDir: process.env.HOME || os.homedir(),
env: process.env,
projectRoot: process.cwd(),
targets: options.targets,
dryRun,View on GitHub (pinned to 8321021c54)