can1357/oh-my-pi · error · Error

secret placeholder key at ${keyPath} is invalid

Error message

secret placeholder key at ${keyPath} is invalid

What it means

The persisted placeholder key file must contain a valid key value. If the file is readable but its contents fail validation (invalidValue is defined — wrong format, corrupted bytes), the loader throws instead of using an untrusted value that would not match tokens encrypted by other processes.

Source

Thrown at packages/coding-agent/src/secrets/index.ts:145

}

/** Read and validate the key file, optionally retrying briefly until a valid key lands. */
async function readPlaceholderKeyFile(keyPath: string, retry: boolean): Promise<string | undefined> {
	const attempts = retry ? 50 : 1;
	let invalidValue: string | undefined;
	for (let attempt = 0; attempt < attempts; attempt++) {
		if (attempt > 0) await Bun.sleep(10);
		try {
			const value = (await Bun.file(keyPath).text()).trim();
			if (PLACEHOLDER_KEY_RE.test(value)) return value;
			if (value.length > 0) invalidValue = value;
		} catch (err) {
			if (isEnoent(err)) return undefined;
			throw err;
		}
	}
	if (invalidValue !== undefined) {
		throw new Error(`secret placeholder key at ${keyPath} is invalid`);
	}
	return undefined;
}

type RawSecretEntry = Omit<SecretEntry, "friendlyName"> & { friendlyName?: unknown };

export {
	deobfuscateSessionContext,
	deobfuscateToolArguments,
	obfuscateMessages,
	obfuscateProviderContext,
} from "./message-transform";
export { type SecretEntry, SecretObfuscator } from "./obfuscator";
export { secretEntriesNeedPlaceholderKey, secretEntryNeedsPlaceholderKey } from "./placeholder";

/**
 * Load secrets from project-local and global secrets.yml files.
 * Project-local entries override global entries with matching content.

View on GitHub (pinned to 9690622007)

Solutions

  1. Delete the invalid key file and let the library regenerate it (note: previously persisted placeholder tokens will need re-derivation)
  2. Restore the file from a valid backup
  3. Avoid manually modifying files under the secrets directory

Example fix

// before
// keyPath contains malformed bytes
throw new Error(`secret placeholder key at ${keyPath} is invalid`);
// after
await fs.rm(keyPath); // regenerate a valid key
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

try {
  key = await getExistingSecretPlaceholderKey(keyPath);
} catch (err) {
  if (err instanceof Error && err.message.includes("is invalid")) {
    await fs.rm(keyPath); // regenerate
    key = await getSecretPlaceholderKey();
  } else throw err;
}

Prevention

When it happens

Trigger: Reading an existing placeholder key whose file content does not decode to a valid key; manual editing or truncation of the key file; disk corruption.

Common situations: Hand-editing files in the secrets directory; syncing secrets across machines with incompatible formats; partial writes from a crash.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/8eca95f131f7dacb. Report an issue: GitHub.