Tencent/WeKnora · error

attachment has no file extension

Error message

attachment has no file extension

What it means

Every IM attachment must carry a file extension, which is used to set attachment FileType and select the document/image parser. If the resolved file name (from the downloader or msg.FileName) has no extension, processing aborts with this error.

Source

Thrown at internal/im/service.go:638

		return nil, nil, nil, err
	}
	defer reader.Close()
	content, err := io.ReadAll(io.LimitReader(reader, maxIMAttachmentBytes+1))
	if err != nil {
		return nil, nil, nil, err
	}
	if len(content) > maxIMAttachmentBytes {
		return nil, nil, nil, fmt.Errorf("attachment exceeds the %d MiB limit", maxIMAttachmentBytes>>20)
	}
	if fileName == "" {
		fileName = msg.FileName
	}
	if msg.MessageType == MessageTypeImage && filepath.Ext(fileName) == "" {
		fileName += ".png"
	}
	ext := strings.ToLower(strings.TrimPrefix(filepath.Ext(fileName), "."))
	if ext == "" {
		return nil, nil, nil, fmt.Errorf("attachment has no file extension")
	}
	attachment := types.MessageAttachment{FileName: fileName, FileType: "." + ext, FileSize: int64(len(content))}
	request := &types.ReadRequest{FileContent: content, FileName: fileName, FileType: ext}
	var result *types.ReadResult
	isImage := msg.MessageType == MessageTypeImage || docparser.IsImageFormat(ext)
	if isImage && s.documentReader != nil {
		result, err = s.documentReader.Read(attachmentCtx, request)
		if err != nil {
			logger.Warnf(ctx, "[IM] image OCR/document parsing failed, continuing with vision input: %v", err)
			result, err = nil, nil
		}
	}
	if result == nil && docparser.IsSimpleFormat(attachment.FileType) {
		result, err = (&docparser.SimpleFormatReader{}).Read(attachmentCtx, request)
	} else if result == nil && !isImage && s.documentReader != nil {
		result, err = s.documentReader.Read(attachmentCtx, request)
	}
	if err != nil {

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Rename the file to include an extension before sending
  2. Ensure your adapter's DownloadFile returns a fileName with an extension (derive from Content-Type/MIME if needed)
  3. Set msg.FileName to a name with an extension in your adapter/webhook layer

Example fix

// before
return reader, "download", nil // no extension
// after
return reader, "download.pdf", nil // extension derived from Content-Type
Defensive patterns

Strategy: validation

Validate before calling

if msg.MessageType == im.MessageTypeFile && filepath.Ext(msg.FileName) == "" {
    return errors.New("file must have an extension")
}

Type guard

func hasExtension(name string) bool { return filepath.Ext(name) != "" }

Prevention

When it happens

Trigger: A file or image message whose fileName (from DownloadFile or msg.FileName) has an empty extension after normalization. Images get a fallback ".png" only when msg.MessageType is image; non-image files with no extension fail.

Common situations: Users uploading extension-less files (common on macOS/Linux); platforms sending sanitized or stripped file names; downloads where the server supplies a generic name with no extension.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/69fb53b1bf2aa03d. Report an issue: GitHub.