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

  1. Choose a different, non-blocked file type (e.g. zip the file only if archives are permitted, or export to PDF).
  2. Share the file via a Drive/cloud link instead of attaching it.
  3. Check the blocked extension list to confirm which extensions are disallowed before attaching.
  4. 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

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


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/40cd93b33c15abba. Report an issue: GitHub.