DayuanJiang/next-ai-draw-io · critical · Error

Failed to encrypt API key. Cannot securely store credentials

Error message

Failed to encrypt API key. Cannot securely store credentials.

What it means

encryptValue uses Electron's safeStorage.encryptString; when the OS keychain/credential store is unavailable (Linux without libsecret, headless environments), encryption throws and the function fails secure rather than storing plaintext.

Source

Thrown at electron/main/config-manager.ts:55

    if (!isEncryptionAvailable()) {
        if (!hasWarnedAboutPlaintext) {
            console.warn(
                "⚠️ SECURITY WARNING: safeStorage not available. " +
                    "API keys will be stored in PLAINTEXT. " +
                    "On Linux, install gnome-keyring or similar for secure storage.",
            )
            hasWarnedAboutPlaintext = true
        }
        return value
    }

    try {
        const encrypted = safeStorage.encryptString(value)
        return ENCRYPTED_PREFIX + encrypted.toString("base64")
    } catch (error) {
        console.error("Encryption failed:", error)
        // Fail secure: don't store if encryption fails
        throw new Error(
            "Failed to encrypt API key. Cannot securely store credentials.",
        )
    }
}

/**
 * Decrypt a sensitive value using safeStorage
 * Returns the original value if it's not encrypted or decryption fails
 */
function decryptValue(value: string): string {
    if (!value || !value.startsWith(ENCRYPTED_PREFIX)) {
        return value
    }
    if (!isEncryptionAvailable()) {
        console.warn(
            "Cannot decrypt value: safeStorage encryption is not available",
        )
        return value

View on GitHub (pinned to 155ef4f7ac)

Solutions

  1. Install/start a secret service: sudo apt install gnome-keyring libsecret-tools, and ensure dbus + gnome-keyring-daemon are running
  2. Set SAFE_STORAGE backend or use password-store backend where supported
  3. Avoid storing API keys in presets on machines without a keyring; enter keys per-session
  4. Check console.error output above the throw for the underlying keychain error
Defensive patterns

Strategy: try-catch

Validate before calling

import { safeStorage } from 'electron'
const canEncrypt = safeStorage.isEncryptionAvailable()

Try / catch

try {
  const enc = encryptValue(apiKey)
} catch (e) {
  if ((e as Error).message.includes('encrypt API key')) {
    warnUserKeyringUnavailable(); storeWithoutKey()
  }
}

Prevention

When it happens

Trigger: Saving a config preset containing an API key on Linux without a secret service (gnome-keyring/KWallet) running, or in a sandboxed/headless Electron environment.

Common situations: Running the Electron app on a bare Linux WM without a keyring daemon, inside CI/containers, or after keyring service crashes.

Related errors


AI-assisted analysis of DayuanJiang/next-ai-draw-io@155ef4f7ac (2026-08-27). Data as JSON: /api/errors/af66d354d03f0509. Report an issue: GitHub.