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
- Delete the invalid key file and let the library regenerate it (note: previously persisted placeholder tokens will need re-derivation)
- Restore the file from a valid backup
- 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
- Never hand-edit files in the secrets directory
- Restore key files only from backups produced by the same library version
- Watch for crashes that truncate writes; recreate keys after disk errors
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
- entry name contains NUL
- secret placeholder key at ${keyPath} exists but is empty or
- source deps tree has no node_modules (${depsDir}); delete it
- unknown filetype: {ft_debug}
- Is a directory
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/8eca95f131f7dacb.
Report an issue: GitHub.