different-ai/openwork · error
The protected OpenWork credential key is invalid.
Error message
The protected OpenWork credential key is invalid.
What it means
Thrown by `decodeKey` in secure-vault-key.mjs when the stored/base64-encoded protected credential key does not decode to exactly `KEY_BYTES` bytes. The module stores an OS-encrypted key for OpenWork-managed OAuth in safeStorage; a decoded key of the wrong length means the stored blob is corrupt, truncated, or was produced by an incompatible version.
Source
Thrown at apps/desktop/electron/secure-vault-key.mjs:48
function backupTimestamp(date) {
const parts = [
date.getUTCFullYear(),
date.getUTCMonth() + 1,
date.getUTCDate(),
date.getUTCHours(),
date.getUTCMinutes(),
date.getUTCSeconds(),
];
return parts.map((part, index) => String(part).padStart(index === 0 ? 4 : 2, "0")).join("");
}
/**
* @param {string} encoded
*/
function decodeKey(encoded) {
const key = Buffer.from(encoded, "base64");
if (key.byteLength !== KEY_BYTES) {
throw new Error("The protected OpenWork credential key is invalid.");
}
return key;
}
/**
* Creates a lazy key provider so Electron does not initialize secure storage
* until a user opts into OpenWork-managed OAuth.
*
* @param {{
* filePath: string;
* loadSafeStorage: () => import("electron").SafeStorage;
* platform?: NodeJS.Platform;
* }} options
*/
export function createDesktopVaultKeyProvider({
filePath,
loadSafeStorage,
platform = process.platform,View on GitHub (pinned to 2b7df46e8a)
Solutions
- Delete the stored key file so the app regenerates a fresh one on next load
- Re-run the key provisioning/persist flow to rewrite the protected key
- Verify the encoded string is complete, valid base64, and produced by the same app version
Example fix
// before
decodeKey(fs.readFileSync(keyPath, 'utf8').trim()); // throws: wrong length
// after
const encoded = fs.readFileSync(keyPath, 'utf8').trim();
if (Buffer.from(encoded, 'base64').byteLength === KEY_BYTES) {
decodeKey(encoded);
} else {
fs.rmSync(keyPath); // regenerate
} Defensive patterns
Strategy: try-catch
Validate before calling
function encodedKeyLooksValid(encoded) {
try { return Buffer.from(encoded, 'base64').byteLength === KEY_BYTES; }
catch { return false; }
} Try / catch
try {
const key = await getKey();
} catch (e) {
if (e.message.includes('credential key is invalid')) {
await regenerateKey(); // delete stored blob and re-provision
} else throw e;
} Prevention
- Never hand-edit the stored key file
- Delete stale key files when migrating userData between machines
- Add a length check before decode in custom tooling
- Regenerate the key rather than trying to repair it
When it happens
Trigger: Calling decodeKey (directly or via the lazy key provider) with a base64 string whose decoded byte length differs from KEY_BYTES — e.g. a truncated file, manual edits to the stored key file, or a key written by a different app version with a different key size.
Common situations: Hand-editing or partially copying the key file; disk corruption or interrupted write; migrating userData between machines with a stale key file; a version change that altered KEY_BYTES.
Related errors
- Operating-system secure storage is unavailable for OpenWork-
- A secure Linux password store is required for OpenWork-manag
- Electron desktop helper is unavailable: ${command}
- Electron desktop helper is unavailable: ${prop}
- Failed to open browser
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/320c64266d234536.
Report an issue: GitHub.