paperclipai/paperclip · warning · Error

Cannot back up missing config at ${filePath}

Error message

Cannot back up missing config at ${filePath}

What it means

Thrown by backupInvalidConfig(configPath?) when the resolved config file path does not exist on disk (fs.existsSync returns false). The function is meant to copy a known-bad config to a .invalid-N sidecar before overwriting it, so it refuses to operate when there is nothing to copy.

Source

Thrown at cli/src/config/store.ts:170

      fs.closeSync(fileDescriptor);
      fileDescriptor = null;
      fs.renameSync(temporaryPath, filePath);
      syncDirectory(path.dirname(filePath));
      return;
    } catch (error) {
      if (fileDescriptor !== null) fs.closeSync(fileDescriptor);
      fs.rmSync(temporaryPath, { force: true });
      const code = error instanceof Error && "code" in error ? error.code : null;
      if (code === "EEXIST") continue;
      throw error;
    }
  }
}

export function backupInvalidConfig(configPath?: string): string {
  const filePath = resolveConfigPath(configPath);
  if (!fs.existsSync(filePath)) {
    throw new Error(`Cannot back up missing config at ${filePath}`);
  }

  for (let suffix = 1; ; suffix += 1) {
    const backupPath = `${filePath}.invalid-${suffix}`;
    try {
      durableCopyFile(filePath, backupPath, fs.constants.COPYFILE_EXCL);
      return backupPath;
    } catch (error) {
      const code = error instanceof Error && "code" in error ? error.code : null;
      if (code === "EEXIST") continue;
      throw error;
    }
  }
}

export function writeConfig(
  config: PaperclipConfig,
  configPath?: string,

View on GitHub (pinned to 67001ec6eb)

Solutions

  1. Check the file exists before calling: only call backupInvalidConfig() when configExists(configPath) returns true, or when readConfig() threw a validation error.
  2. If you intended to back up, confirm the resolved path (resolveConfigPath) matches where the file actually lives.
  3. If the config genuinely does not exist yet, skip the backup step — there is nothing to preserve.

Example fix

// before
import { backupInvalidConfig } from "./config/store.js";
const backup = backupInvalidConfig(path); // throws if file missing

// after
import { backupInvalidConfig, configExists } from "./config/store.js";
const backup = configExists(path) ? backupInvalidConfig(path) : null;
Defensive patterns

Strategy: validation

Validate before calling

import { configExists, backupInvalidConfig } from "./config/store.js";

function tryBackupInvalidConfig(configPath?: string): string | null {
  if (!configExists(configPath)) return null;
  return backupInvalidConfig(configPath);
}

Type guard

import fs from "node:fs";

function configExistsAt(p: string): boolean {
  try { return fs.statSync(p).isFile(); } catch { return false; }
}

Try / catch

import { backupInvalidConfig } from "./config/store.js";

let backup;
try {
  backup = backupInvalidConfig(configPath);
} catch (err) {
  if (err instanceof Error && err.message.startsWith("Cannot back up missing config")) {
    backup = null; // nothing to back up; proceed without
  } else throw err;
}

Prevention

When it happens

Trigger: Called backupInvalidConfig() but resolveConfigPath() resolved to a path where no file exists — either because no .paperclip/config.json was found in ancestor directories and the default home path was never created, or because the caller passed an explicit configPath that points at a missing file.

Common situations: 1) A fresh machine with no Paperclip config yet, where a code path unconditionally calls backupInvalidConfig(). 2) A race where the config was deleted between the existence check and the backup call. 3) Passing a wrong --config flag pointing at a non-existent file.

Related errors


AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12). Data as JSON: /api/errors/e26dc187ace05e08. Report an issue: GitHub.