CherryHQ/cherry-studio · error · Error
Feishu rejected the file upload for "${file.filename}" (no f
Error message
Feishu rejected the file upload for "${file.filename}" (no file_key) — likely over Feishu's file size limit (~30MB) or the bot lacks file-send capability What it means
Companion to 105 for the generic-file branch: client.im.file.create with file_type 'stream' returns no file_key. Same unwrapped-data contract — a null file_key means the upload silently failed, so the adapter throws an enriched error instead of routing through ensureFeishuSuccess.
Source
Thrown at src/main/ai/channels/adapters/feishu/FeishuAdapter.ts:598
`Feishu rejected the image upload for "${file.filename}" (no image_key) — likely over Feishu's image size limit (~10MB) or the bot lacks image-send capability`
)
}
ensureFeishuSuccess(
await this.client.im.message.create({
params: { receive_id_type: 'chat_id' },
data: { receive_id: chatId, msg_type: 'image', content: JSON.stringify({ image_key: imageKey }) }
}),
'Send Feishu image'
)
} else {
const uploaded = await this.client.im.file.create({
data: { file_type: 'stream', file_name: file.filename, file: buffer }
})
const fileKey = uploaded?.file_key
if (!fileKey) {
this.log.warn('Feishu file upload returned no file_key', { chatId, filename: file.filename, size: file.size })
throw new Error(
`Feishu rejected the file upload for "${file.filename}" (no file_key) — likely over Feishu's file size limit (~30MB) or the bot lacks file-send capability`
)
}
ensureFeishuSuccess(
await this.client.im.message.create({
params: { receive_id_type: 'chat_id' },
data: { receive_id: chatId, msg_type: 'file', content: JSON.stringify({ file_key: fileKey }) }
}),
'Send Feishu file'
)
}
this.log.info('Sent file', { chatId, filename: file.filename, size: file.size, mediaType: file.media_type })
}
async sendTypingIndicator(chatId: string): Promise<void> {
await this.setChatReaction(chatId, REACTION_THINKING)View on GitHub (pinned to 726446b54c)
Solutions
- Keep attachments under ~30MB; chunk or host large files externally and send a link instead.
- Confirm the bot has file-send permission in the Feishu console.
- Sanitize file.filename (ASCII-safe, no path separators) before upload.
- Retry once on a null file_key for transient upload failures.
Defensive patterns
Strategy: validation
Validate before calling
// Validate size before upload.
function isWithinFeishuFileLimit(file: FileAttachment): boolean {
const bytes = Math.ceil((file.data.length * 3) / 4)
return bytes <= 30 * 1024 * 1024
} Type guard
function isFeishuFileRejected(e: unknown): e is Error {
return e instanceof Error && e.message.startsWith('Feishu rejected the file upload')
} Try / catch
try {
await feishu.sendFile(chatId, file)
} catch (e) {
if (isFeishuFileRejected(e)) {
await feishu.sendMessage(chatId, `[file too large to upload: ${file.filename}]`)
return
}
throw e
} Prevention
- Keep attachments under 30MB; host larger files externally and send a link.
- Confirm file-send permission in the Feishu console.
- Sanitize filenames to ASCII-safe values before upload.
When it happens
Trigger: Non-image file path: file.media_type does not start with 'image/', client.im.file.create resolves but uploaded.file_key is undefined/null/empty. Logged with chatId/filename/size, then thrown.
Common situations: File over Feishu's ~30MB file limit, bot lacking file-send capability, invalid file bytes, or filename containing characters the SDK rejects.
Related errors
- Feishu rejected the image upload for "${file.filename}" (no
- ${action} failed: ${unwrapped.msg || unwrapped.message || `c
- Feishu WebSocket connection failed: ${error instanceof Error
- Client is not connected
- Invalid JSON from Feishu registration API: ${text.slice(0, 2
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/13e21439fb34684a.
Report an issue: GitHub.