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.

Solutions

  1. Delete the stored key file so the app regenerates a fresh one on next load
  2. Re-run the key provisioning/persist flow to rewrite the protected key
  3. 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

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


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/320c64266d234536. Report an issue: GitHub.

Appendix: 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)