larksuite/cli · error
file extension %q is not allowed as a mail attachment
Error message
file extension %q is not allowed as a mail attachment
What it means
CheckBlockedExtension rejects attachment filenames whose extension appears in the mail blocked-extension blacklist (e.g. executable/script types that mail systems refuse). The check is case-insensitive on the lowercased extension; an empty extension is allowed. Wrapped into a typed ValidationError by the mail command layer.
Source
Thrown at shortcuts/mail/filecheck/filecheck.go:127
"vb": {},
"vbe": {},
"vbs": {},
"vbscript": {},
"ws": {},
"wsc": {},
"wsf": {},
"wsh": {},
"zsh": {},
}
// CheckBlockedExtension returns an error if the filename has a blocked extension.
func CheckBlockedExtension(filename string) error {
ext := strings.ToLower(strings.TrimPrefix(filepath.Ext(filename), "."))
if ext == "" {
return nil
}
if _, ok := blockedExtensions[ext]; ok {
return fmt.Errorf("file extension %q is not allowed as a mail attachment", "."+ext) //nolint:forbidigo // intermediate mail file-format check; mail command layer wraps into typed ValidationError.
}
return nil
}
// allowedInlineExtensions is the whitelist of file extensions allowed for
// inline images. Only well-supported image formats are included.
var allowedInlineExtensions = map[string]struct{}{
"jpg": {},
"jpeg": {},
"png": {},
"gif": {},
"webp": {},
}
// allowedInlineMIMETypes is the whitelist of MIME types allowed for inline
// images, checked via content sniffing (http.DetectContentType).
var allowedInlineMIMETypes = map[string]struct{}{
"image/jpeg": {},View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Choose a different, non-blocked file type (e.g. zip the file only if archives are permitted, or export to PDF).
- Share the file via a Drive/cloud link instead of attaching it.
- Check the blocked extension list to confirm which extensions are disallowed before attaching.
- Rename to an allowed extension only if the content type genuinely changes (never spoof the extension).
Example fix
// before
b.AddFileAttachment("installer.exe") // blocked extension
// after
b.AddFileAttachment("installer.pdf") // or share a download link Defensive patterns
Strategy: validation
Validate before calling
if err := filecheck.CheckBlockedExtension(filename); err != nil {
return fmt.Errorf("cannot attach %s: %w", filename, err)
}
b.AddFileAttachment(filename) Try / catch
if err := b.AddFileAttachment(path); err != nil {
var verr *ValidationError
if errors.As(err, &verr) && strings.Contains(err.Error(), "not allowed as a mail attachment") {
return fmt.Errorf("use a Drive link for %s", path)
}
return err
} Prevention
- Pre-screen attachment lists against the blocked extension list before adding them.
- Offer a Drive-link fallback flow for executables and scripts.
- Never bypass the check by renaming files to a fake extension.
When it happens
Trigger: Calling AddFileAttachment (directly or via statAttachmentFiles / uploadToDriveForTemplate) with a filename whose extension is in blockedExtensions — e.g. .exe, .bat, .js, .sh — including uppercase variants like REPORT.EXE.
Common situations: Users attaching build artifacts or installers (app.exe, setup.msi); scripts (.sh, .bat, .ps1) shared as attachments; macro-enabled Office files blocked by security policy; archives hiding executables.
Related errors
- emlbuilder: EML size %.1f MB exceeds the %.0f MB limit
- inline image extension %q is not allowed; supported formats:
- path validation failed
- %s: path must be absolute, got %q
- %s: cannot stat %q: %w
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/40cd93b33c15abba.
Report an issue: GitHub.