paperclipai/paperclip · error · Error

Invalid decision signing key at ${keyPath} (must be at least

Error message

Invalid decision signing key at ${keyPath} (must be at least ${MIN_SECRET_LENGTH} characters); remove the file to regenerate it or set PAPERCLIP_DECISION_SIGNING_SECRET

What it means

Error "Invalid decision signing key at ${keyPath} (must be at least ${MIN_SECRET_LENGTH} characters); remove the file to regenerate it or set PAPERCLIP_DECISION_SIGNING_SECRET" thrown in paperclipai/paperclip.

Source

Thrown at server/src/services/decision-signing.ts:70

  const mode = stats.mode & 0o777;
  if ((mode & 0o077) !== 0) {
    chmodSync(directoryPath, 0o700);
    stats = lstatSync(directoryPath);
    if (!stats.isDirectory()) {
      throw new Error(`Decision signing secrets directory at ${directoryPath} must be a directory`);
    }
    assertOwnedByCurrentUser(stats, `Decision signing secrets directory at ${directoryPath}`);
    if ((stats.mode & 0o077) !== 0) {
      throw new Error(`Decision signing secrets directory at ${directoryPath} must have permissions 0700`);
    }
  }
}

function readGeneratedSecret(keyPath: string): string {
  enforceKeyFilePermissions(keyPath);
  const existing = readFileSync(keyPath, "utf8").trim();
  if (existing.length < MIN_SECRET_LENGTH) {
    throw new Error(
      `Invalid decision signing key at ${keyPath} (must be at least ${MIN_SECRET_LENGTH} characters); remove the file to regenerate it or set PAPERCLIP_DECISION_SIGNING_SECRET`,
    );
  }
  return existing;
}

function isAlreadyExists(error: unknown) {
  return (error as NodeJS.ErrnoException).code === "EEXIST";
}

function isNotFound(error: unknown) {
  return (error as NodeJS.ErrnoException).code === "ENOENT";
}

function loadOrCreateGeneratedSecret(): string {
  const keyPath = resolveGeneratedSecretFilePath();
  const secretsDirectoryPath = path.dirname(keyPath);
  try {

View on GitHub (pinned to 120ae5428f)

Solutions

  1. Remove the invalid key file so a new one is regenerated, or set PAPERCLIP_DECISION_SIGNING_SECRET to a value of at least the minimum length.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at server/src/services/decision-signing.ts:70 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of paperclipai/paperclip@120ae5428f (2026-08-18). Data as JSON: /api/errors/174c22c7563fc0a2. Report an issue: GitHub.