thedotmack/claude-mem · error

[SETTINGS] Failed to auto-migrate settings file:

Error message

[SETTINGS] Failed to auto-migrate settings file:

What it means

Not a thrown exception but a swallowed warning logged in loadFromFile when the automatic schema migration fails. When a legacy settings file has the shape { env: {...} } with no peer root keys, the loader flattens it in memory and then attempts writeJsonFileAtomic(settingsPath, flatSettings) to persist the new flat schema. This warning fires when that atomic write fails — typically due to filesystem permission errors, a read-only data directory, ENOSPC, EACCES/EPERM on the settings file, or a disk I/O failure. The migration itself still succeeds in memory, so settings load proceeds with defaults merged; the file just remains in the legacy nested format and will be re-migrated on every load.

Source

Thrown at src/shared/SettingsDefaultsManager.ts:332

      const settingsData = readFileSync(settingsPath, 'utf-8');
      const settings = parseJsonWithBom<Record<string, any>>(settingsData);

      let flatSettings = settings;
      const hasNestedEnv = settings.env && typeof settings.env === 'object' && !Array.isArray(settings.env);
      const hasPeerRootKeys = hasNestedEnv && Object.keys(settings).some((key) => key !== 'env');
      if (hasNestedEnv) {
        flatSettings = settings.env;

        // A legacy file containing only `{ env: {...} }` can be flattened
        // safely. If it also contains peer root keys (hooks, permissions,
        // theme, etc.), retain the wrapper: flattening would destroy user data.
        if (!hasPeerRootKeys) {
          try {
            writeJsonFileAtomic(settingsPath, flatSettings);
            // stderr, never stdout — same JSON-on-stdout contract as above.
            console.warn('[SETTINGS] Migrated settings file from nested to flat schema:', settingsPath);
          } catch (error: unknown) {
            console.warn('[SETTINGS] Failed to auto-migrate settings file:', settingsPath, error instanceof Error ? error.message : String(error));
            // Continue with in-memory migration even if write fails
          }
        }
      }

      if (flatSettings.CLAUDE_MEM_TELEGRAM_TRIGGER_TYPES === LEGACY_TELEGRAM_TRIGGER_TYPES) {
        flatSettings = {
          ...flatSettings,
          CLAUDE_MEM_TELEGRAM_TRIGGER_TYPES: this.DEFAULTS.CLAUDE_MEM_TELEGRAM_TRIGGER_TYPES,
        };

        try {
          writeJsonFileAtomic(
            settingsPath,
            hasPeerRootKeys ? { ...settings, env: flatSettings } : flatSettings,
          );
          // stderr, never stdout — same JSON-on-stdout contract as above.
          console.warn('[SETTINGS] Migrated Telegram trigger types off the legacy default:', settingsPath);

View on GitHub (pinned to 8bc631a71a)

Solutions

  1. Check filesystem permissions on the settings file and its parent directory; ensure the process user has write access (chmod/chown the file or directory).
  2. Free disk space if the error message contains ENOSPC, since a full disk prevents the atomic write.
  3. Verify the settings file is not read-only or locked by another process; close editors or tools holding the file and retry.
  4. If the directory is intentionally read-only, accept the warning: settings still load correctly in memory, or move the data dir to a writable location.
  5. Manually rewrite the settings file in the flat schema (move the contents of the env object to the top level) so the auto-migration is no longer needed.
  6. If the error persists, replace the settings file by deleting it so a fresh file with defaults is created on next load, then reapply custom settings.
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at src/shared/SettingsDefaultsManager.ts:259 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of thedotmack/claude-mem@8bc631a71a (2026-09-09). Data as JSON: /api/errors/ef954d5edef596b6. Report an issue: GitHub.