iflytek/astron-agent · error
model.encryptionFailed
Error message
model.encryptionFailed
What it means
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.
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.
Example fix
// before
for (const char of text) {
const charBytes = encoder.encode(char).length;
if (charBytes > maxChunkBytes) throw new Error(i18next.t('model.encryptionFailed'));
// after
const sanitized = text.replace(/[\u200B-\u200D\uFEFF]/g, '').trim();
if (/[^\x00-\x7F]/.test(sanitized)) {
throw new Error(i18next.t('model.apiKeyAsciiOnly'));
}
for (const char of sanitized) {
const charBytes = encoder.encode(char).length;
if (charBytes > maxChunkBytes) throw new Error(i18next.t('model.encryptionFailed')); Defensive patterns
Strategy: validation
Validate before calling
// before calling encryptApiKey
if (!/^[\x20-\x7E]+$/.test(apiKey)) {
form.setFields([{ name: 'apiKey', errors: ['API Key 只能包含 ASCII 可见字符'] }]);
return;
} Type guard
function isAsciiPrintable(s: string): boolean {
return /^[\x20-\x7E]+$/.test(s);
} Try / catch
try {
const encrypted = await encryptApiKey(apiKey, publicKey);
} catch (e) {
if (e.message === i18next.t('model.encryptionFailed')) {
form.setFields([{ name: 'apiKey', errors: [e.message] }]);
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- MODEL_APIKEY_LOAD_ERROR
- MODEL_APIKEY_LOAD_ERROR
- MODEL_API_KEY_NOT_FOUND
- -40006
- Encrypted data cannot be empty
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/12d7ead2dfc2e9b4.
Report an issue: GitHub.
Appendix: source
Thrown at console/frontend/src/pages/model-management/utils/encrypt-api-key.ts:40
const splitTextByUtf8ByteLength = (
text: string,
maxChunkBytes: number
): string[] => {
if (!text) {
return [''];
}
const encoder = new TextEncoder();
const chunks: string[] = [];
let currentChunk = '';
let currentChunkBytes = 0;
for (const char of text) {
const charBytes = encoder.encode(char).length;
if (charBytes > maxChunkBytes) {
throw new Error(i18next.t('model.encryptionFailed'));
}
if (currentChunkBytes + charBytes > maxChunkBytes) {
chunks.push(currentChunk);
currentChunk = char;
currentChunkBytes = charBytes;
continue;
}
currentChunk += char;
currentChunkBytes += charBytes;
}
if (currentChunk) {
chunks.push(currentChunk);
}
return chunks;View on GitHub (pinned to 5e758547a8)