affaan-m/ECC · error
Another ECC process is updating Claude settings
Error message
Another ECC process is updating Claude settings: ${settingsPath}. If no ECC process is active, inspect and remove ${lockPath}. What it means
acquireSettingsLock tries to create the lock file exclusively; on EEXIST it attempts recovery of a stale lock, and if recovery also fails it concludes another ECC process holds the settings lock. It aborts with instructions pointing at both the settings path and the lock file so the user can verify no process is running and manually clean up.
Solutions
- Wait for the running ECC process to finish, or kill it if it is hung.
- Verify no ECC process is active (ps), then manually remove the lock file shown in the message and retry.
- Serialize ECC invocations (don't run install/uninstall concurrently in scripts).
- In containers, ensure each container has a single ECC process and clean lock files on restart.
Example fix
// before (concurrent)
run('ecc install') ; run('ecc uninstall') // parallel
// after
await run('ecc install'); await run('ecc uninstall') // sequential Defensive patterns
Strategy: retry
Validate before calling
// guard before invoking ECC settings operations
import { existsSync } from 'fs';
const lockPath = settingsPath + '.lock';
if (existsSync(lockPath)) {
const running = execSync('pgrep -f ecc-install || true').toString().trim();
if (running) throw new Error('Another ECC process holds the settings lock');
} Try / catch
try {
await withSettingsLock(settingsPath, work);
} catch (e) {
if (e.message.includes('Another ECC process is updating Claude settings')) {
await wait(2000);
return acquireSettingsLock(settingsPath); // bounded retry
} else if (e.message.includes('inspect and remove')) {
// no active process path: remove stale lock, then retry once
} else throw e;
} Prevention
- Serialize all ECC install/uninstall invocations in scripts.
- Use a process manager to prevent orphaned ECC processes holding locks.
- Clean up lock files on container restart when no process could survive.
When it happens
Trigger: Calling any settings-mutating ECC command while another ECC process holds the lock (exclusive create returns EEXIST), and recoverSettingsLock cannot determine the lock is stale (holder still alive or lock identity ambiguous).
Common situations: Two installers run concurrently (terminal + IDE automation); a previous ECC process crashed leaving a lock and the PID check cannot safely recover it; container environments where PID reuse confuses staleness detection.
Related errors
- Another Nasiko lifecycle operation is already in progress…
- Another Nasiko lifecycle operation won lock acquisition
- Another Nasiko lifecycle operation won stale-lock recovery
- capsule.busy
- capsule.lock_lost
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/14b6107e860df40e.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/install/claude-settings-lock.js:145
} finally {
fs.rmSync(recoveryPath, { recursive: true, force: true });
fs.rmSync(quarantinePath, { force: true });
}
}
function acquireSettingsLock(settingsPath) {
const lockPath = `${settingsPath}.ecc.lock`;
fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
try {
return createSettingsLock(lockPath);
} catch (error) {
if (!error || error.code !== 'EEXIST') {
throw error;
}
}
const recovered = recoverSettingsLock(lockPath);
if (recovered) return recovered;
throw new Error(
`Another ECC process is updating Claude settings: ${settingsPath}. `
+ `If no ECC process is active, inspect and remove ${lockPath}.`
);
}
function runWithSettingsLock(settingsPath, callback) {
const releaseLock = acquireSettingsLock(settingsPath);
let primaryError = null;
let result;
try {
result = callback();
} catch (error) {
primaryError = error;
}
let releaseError = null;
try {
releaseLock();View on GitHub (pinned to 8321021c54)