affaan-m/ECC · error

Unable to update Claude settings at

Error message

Unable to update Claude settings at ${settingsPath}

What it means

update() retries a read-modify-write cycle against the Claude settings file, detecting concurrent modifications via the ECC_SETTINGS_CHANGED sentinel. If the retry loop is exhausted (or fails for a non-ECC_SETTINGS_CHANGED reason it rethrows immediately), it throws this error indicating the settings file could not be updated at the given path. It is a deliberate failure rather than a silent partial write.

Solutions

  1. Rerun the operation once no other install/update process is running; transient races resolve on retry.
  2. Identify concurrent writers (another terminal running the installer, CI job, file-sync daemon) and stop them before updating.
  3. Exclude ~/.claude/settings.json from cloud-sync/watcher tools that rewrite it during operations.
  4. Check the `cause`/original error if a non-ECC_SETTINGS_CHANGED error surfaced and fix that root problem first.
Defensive patterns

Strategy: retry

Try / catch

try {
  await updateSettingsAtomic(path, fn);
} catch (error) {
  if (error.message.startsWith('Unable to update Claude settings')) {
    await new Promise(r => setTimeout(r, 250));
    await updateSettingsAtomic(path, fn); // single manual retry after quiescing writers
  } else throw error;
}

Prevention

When it happens

Trigger: Calling updateSettingsAtomic(path, fn) while another process repeatedly rewrites the settings file so every attempt sees ECC_SETTINGS_CHANGED, exhausting maxAttempts; or the underlying update function throwing a non-retryable error.

Common situations: Two installs/updates racing on the same machine (CI plus a local dev server), a file watcher or sync tool (Dropbox/OneDrive) constantly touching settings.json, or an unrelated thrown error inside the update callback being mistaken for a lock problem.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/8233cb72be87227a. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/install/claude-settings.js:441

          settingsPath,
          `${JSON.stringify(result.settings, null, 2)}\n`,
          {
            encoding: 'utf8',
            mode: snapshot.mode,
            validateParent,
            beforeRename() {
              assertSettingsSnapshotUnchanged(settingsPath, snapshot);
            },
          }
        );
        return result;
      } catch (error) {
        if (error.code !== 'ECC_SETTINGS_CHANGED' || attempt === maxAttempts) {
          throw error;
        }
      }
    }
    throw new Error(`Unable to update Claude settings at ${settingsPath}`);
  };
  if (options.lockHeld) {
    return update();
  }
  return runWithSettingsLock(settingsPath, update);
}

function reference(event, id) {
  return { event, id };
}

function entriesMatchingId(entries, id) {
  return entries
    .map((entry, index) => ({ entry, index }))
    .filter(candidate => isJsonObject(candidate.entry) && candidate.entry.id === id);
}

function assertUnambiguousMatch(entries, event, id) {

View on GitHub (pinned to 8321021c54)