{"record":{"id":"8eca95f131f7dacb","repo":"can1357/oh-my-pi","slug":"secret-placeholder-key-at-keypath-is-invalid","errorCode":null,"errorMessage":"secret placeholder key at ${keyPath} is invalid","messagePattern":"secret placeholder key at (.+?) is invalid","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/secrets/index.ts","lineNumber":145,"sourceCode":"}\n\n/** Read and validate the key file, optionally retrying briefly until a valid key lands. */\nasync function readPlaceholderKeyFile(keyPath: string, retry: boolean): Promise<string | undefined> {\n\tconst attempts = retry ? 50 : 1;\n\tlet invalidValue: string | undefined;\n\tfor (let attempt = 0; attempt < attempts; attempt++) {\n\t\tif (attempt > 0) await Bun.sleep(10);\n\t\ttry {\n\t\t\tconst value = (await Bun.file(keyPath).text()).trim();\n\t\t\tif (PLACEHOLDER_KEY_RE.test(value)) return value;\n\t\t\tif (value.length > 0) invalidValue = value;\n\t\t} catch (err) {\n\t\t\tif (isEnoent(err)) return undefined;\n\t\t\tthrow err;\n\t\t}\n\t}\n\tif (invalidValue !== undefined) {\n\t\tthrow new Error(`secret placeholder key at ${keyPath} is invalid`);\n\t}\n\treturn undefined;\n}\n\ntype RawSecretEntry = Omit<SecretEntry, \"friendlyName\"> & { friendlyName?: unknown };\n\nexport {\n\tdeobfuscateSessionContext,\n\tdeobfuscateToolArguments,\n\tobfuscateMessages,\n\tobfuscateProviderContext,\n} from \"./message-transform\";\nexport { type SecretEntry, SecretObfuscator } from \"./obfuscator\";\nexport { secretEntriesNeedPlaceholderKey, secretEntryNeedsPlaceholderKey } from \"./placeholder\";\n\n/**\n * Load secrets from project-local and global secrets.yml files.\n * Project-local entries override global entries with matching content.","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/secrets/index.ts#L127-L163","documentation":"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.","triggerScenarios":"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.","commonSituations":"Hand-editing files in the secrets directory; syncing secrets across machines with incompatible formats; partial writes from a crash.","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"],"exampleFix":"// before\n// keyPath contains malformed bytes\nthrow new Error(`secret placeholder key at ${keyPath} is invalid`);\n// after\nawait fs.rm(keyPath); // regenerate a valid key","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n  key = await getExistingSecretPlaceholderKey(keyPath);\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"is invalid\")) {\n    await fs.rm(keyPath); // regenerate\n    key = await getSecretPlaceholderKey();\n  } else throw err;\n}","preventionTips":["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"],"tags":["secrets","filesystem","corruption"],"backgroundTag":"secret-key-invalid","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}