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 valueView on GitHub (pinned to 155ef4f7ac)
Solutions
- Install/start a secret service: sudo apt install gnome-keyring libsecret-tools, and ensure dbus + gnome-keyring-daemon are running
- Set SAFE_STORAGE backend or use password-store backend where supported
- Avoid storing API keys in presets on machines without a keyring; enter keys per-session
- 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
- Check safeStorage.isEncryptionAvailable() before offering 'save API key' in the UI
- On Linux, ensure gnome-keyring/KWallet and dbus are running
- Never fall back to storing plaintext silently — ask the user
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
- Invalid preset name
- Server startup timeout after ${timeout}ms
- Server script not found at ${serverPath}. Please ensure the
AI-assisted analysis of DayuanJiang/next-ai-draw-io@155ef4f7ac (2026-08-27).
Data as JSON: /api/errors/af66d354d03f0509.
Report an issue: GitHub.