{"record":{"id":"12d7ead2dfc2e9b4","repo":"iflytek/astron-agent","slug":"model-encryptionfailed","errorCode":null,"errorMessage":"model.encryptionFailed","messagePattern":"model\\.encryptionFailed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"console/frontend/src/pages/model-management/utils/encrypt-api-key.ts","lineNumber":40,"sourceCode":"\nconst splitTextByUtf8ByteLength = (\n  text: string,\n  maxChunkBytes: number\n): string[] => {\n  if (!text) {\n    return [''];\n  }\n\n  const encoder = new TextEncoder();\n  const chunks: string[] = [];\n  let currentChunk = '';\n  let currentChunkBytes = 0;\n\n  for (const char of text) {\n    const charBytes = encoder.encode(char).length;\n\n    if (charBytes > maxChunkBytes) {\n      throw new Error(i18next.t('model.encryptionFailed'));\n    }\n\n    if (currentChunkBytes + charBytes > maxChunkBytes) {\n      chunks.push(currentChunk);\n      currentChunk = char;\n      currentChunkBytes = charBytes;\n      continue;\n    }\n\n    currentChunk += char;\n    currentChunkBytes += charBytes;\n  }\n\n  if (currentChunk) {\n    chunks.push(currentChunk);\n  }\n\n  return chunks;","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/frontend/src/pages/model-management/utils/encrypt-api-key.ts#L22-L58","documentation":"Inside splitTextByUtf8ByteLength, a single character whose UTF-8 byte length exceeds maxChunkBytes cannot fit into any chunk, so the function throws the localized error 'model.encryptionFailed'. RSA encryption via JSEncrypt requires splitting the API key into blocks smaller than the key size, and no single character may exceed a block.","triggerScenarios":"Encrypting a model API key containing a character (typically a multi-byte CJK character or emoji, or an extremely small RSA key size) where encoder.encode(char).length > maxChunkBytes — e.g. a 3-byte character with a 1024-bit key leaving only 1-byte chunks after OAEP/PKCS1 overhead.","commonSituations":"Users pasting API keys that include non-ASCII characters (Chinese comments, full-width punctuation, invisible BOM/zero-width chars); very small RSA public keys configured on the server; copy-paste introducing smart quotes.","solutions":["Validate the API key input to reject non-ASCII characters before encrypting; show a field-level validation message.","Trim/invisible-character-strip the key input (remove BOM, zero-width spaces, whitespace) before calling encryptApiKey.","Use a larger RSA key (2048-bit) server-side so maxChunkBytes comfortably exceeds any single character.","Catch the error and surface i18next key resolution too — confirm 'model.encryptionFailed' exists in locale files so users see a readable message."],"exampleFix":"// before\nfor (const char of text) {\n  const charBytes = encoder.encode(char).length;\n  if (charBytes > maxChunkBytes) throw new Error(i18next.t('model.encryptionFailed'));\n// after\nconst sanitized = text.replace(/[\\u200B-\\u200D\\uFEFF]/g, '').trim();\nif (/[^\\x00-\\x7F]/.test(sanitized)) {\n  throw new Error(i18next.t('model.apiKeyAsciiOnly'));\n}\nfor (const char of sanitized) {\n  const charBytes = encoder.encode(char).length;\n  if (charBytes > maxChunkBytes) throw new Error(i18next.t('model.encryptionFailed'));","handlingStrategy":"validation","validationCode":"// before calling encryptApiKey\nif (!/^[\\x20-\\x7E]+$/.test(apiKey)) {\n  form.setFields([{ name: 'apiKey', errors: ['API Key 只能包含 ASCII 可见字符'] }]);\n  return;\n}","typeGuard":"function isAsciiPrintable(s: string): boolean {\n  return /^[\\x20-\\x7E]+$/.test(s);\n}","tryCatchPattern":"try {\n  const encrypted = await encryptApiKey(apiKey, publicKey);\n} catch (e) {\n  if (e.message === i18next.t('model.encryptionFailed')) {\n    form.setFields([{ name: 'apiKey', errors: [e.message] }]);\n  }\n}","preventionTips":["Sanitize pasted keys: trim and strip BOM/zero-width characters","Restrict the API-key input field to ASCII via input validation","Use RSA keys of at least 2048 bits server-side","Ensure locale files define model.encryptionFailed so users see a readable message"],"tags":["encryption","rsa","utf-8","input-validation","i18n"],"backgroundTag":"invalid-argument-format","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}