CherryHQ/cherry-studio · error · Error

Private key must be a non-empty string

Error message

Private key must be a non-empty string

What it means

formatPrivateKey validates its input up front: a falsy or non-string value throws because all subsequent parsing (regex replace, PEM detection) assumes a real string. This is the entry guard for the private-key normalization helpers used when signing requests (e.g. JWT/Service Account auth).

Source

Thrown at packages/aiCore/src/core/providers/core/utils.ts:13

/**
 * Provider 工具函数和错误类
 * 合并自 utils.ts 和 errors.ts
 */

// ==================== 私钥格式化工具 ====================

/**
 * 格式化私钥,确保它包含正确的PEM头部和尾部
 */
export function formatPrivateKey(privateKey: string): string {
  if (!privateKey || typeof privateKey !== 'string') {
    throw new Error('Private key must be a non-empty string')
  }

  // 先处理 JSON 字符串中的转义换行符
  const key = privateKey.replace(/\\n/g, '\n')

  // 检查是否已经是正确格式的 PEM 私钥
  const hasBeginMarker = key.includes('-----BEGIN PRIVATE KEY-----')
  const hasEndMarker = key.includes('-----END PRIVATE KEY-----')

  if (hasBeginMarker && hasEndMarker) {
    // 已经是 PEM 格式,但可能格式不规范,重新格式化
    return normalizePemFormat(key)
  }

  // 如果没有完整的 PEM 头尾,尝试重新构建
  return reconstructPemKey(key)
}

View on GitHub (pinned to 726446b54c)

Solutions

  1. Load the private key from its source (env var, file) and confirm it is a non-empty string before calling.
  2. If the key lives in a service-account JSON, extract the privateKey field (json.private_key), not the whole object.
  3. Fail fast at app startup with a clear message when the key is missing.

Example fix

// before
formatPrivateKey(process.env.SERVICE_ACCOUNT_KEY) // undefined if unset
// after
const key = process.env.GCP_PRIVATE_KEY
if (!key) throw new Error('GCP_PRIVATE_KEY not set')
formatPrivateKey(key)
Defensive patterns

Strategy: validation

Validate before calling

if (!privateKey || typeof privateKey !== 'string') {
  throw new Error('privateKey is missing — set GCP_PRIVATE_KEY / service account key')
}
formatPrivateKey(privateKey)

Type guard

function isNonEmptyString(v: unknown): v is string {
  return typeof v === 'string' && v.length > 0
}

Prevention

When it happens

Trigger: Calling formatPrivateKey(undefined), formatPrivateKey(''), formatPrivateKey(null), or passing a non-string (number, object) — usually because a service-account private key was not loaded from env/file.

Common situations: SERVICE_ACCOUNT_KEY / privateKey env var not set; reading the key from a JSON config that was parsed wrong; a form field left empty; passing the parsed JSON object instead of its privateKey field.

Related errors


AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12). Data as JSON: /api/errors/507bb91e7b1b35fe. Report an issue: GitHub.