[PR #23641] Fix file type misclassification in logs interface #30335

Closed
opened 2026-02-21 20:47:18 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/langgenius/dify/pull/23641

State: closed
Merged: Yes


Summary

This PR resolves the issue where JPG files are occasionally displayed as document icons instead of image previews in the apps/{id}/logs interface when viewing historical chat records. The root cause was backend file type misclassification being blindly trusted by the frontend.

Problem Analysis:

  • Backend file_factory.py prioritizes API-specified type over detected file type
  • Frontend getProcessedFilesFromResponse directly used backend type without validation
  • Result: Image files incorrectly classified as type: "document" display as file icons

Solution - Dual Verification System:
Implemented robust dual verification that validates both filename and MIME type before correcting any classification:

const detectedTypeFromFileName = getSupportFileType(fileItem.filename, '')
const detectedTypeFromMime = getSupportFileType('', fileItem.mime_type)

// Only correct when both methods agree AND differ from backend
if (detectedTypeFromFileName && 
    detectedTypeFromMime && 
    detectedTypeFromFileName === detectedTypeFromMime && 
    detectedTypeFromFileName \!== fileItem.type) {
  supportFileType = detectedTypeFromFileName
}

Key Features:

  • Zero Hardcoding: Uses existing FILE_EXTS constants and getSupportFileType function
  • Full Type Coverage: Supports image, video, audio, document, custom file types
  • Conflict Detection: Prevents false corrections when filename/MIME disagree
  • Backward Compatible: Correctly classified files remain unchanged
  • TypeScript Safe: Fixed potential undefined value error

Test Coverage:

  • Total Tests: 49 test cases (11 new tests for dual verification logic)
  • Coverage: 96.69% statements, 94.04% branches
  • Scenarios Tested:
    • Original problem: JPG with document type → corrected to image
    • Multi-media support: MP4 video, MP3 audio correction
    • Reverse correction: PDF misclassified as image → corrected to document
    • Conflict detection: PDF filename + JPG MIME → no change (safety)
    • Edge cases: Missing filename/MIME, unknown extensions

Safety Verification:

Scenario Filename MIME Type Backend Type Detection Result Final Type Action
Original Issue image.jpg image/jpeg document image = image image Corrected
Correct File image.jpg image/jpeg image image = image image Unchanged
Conflict Case doc.pdf image/jpeg document document ≠ image document Safe: No change
Reverse Error doc.pdf application/pdf image document = document document Corrected

Fixes #23637

Screenshots

Before After
JPG files displayed as document icons in logs JPG files correctly displayed as image thumbnails with preview

Checklist

  • This change requires a documentation update, included: Dify Document
  • I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.
  • I ran dev/reformat(backend) and cd web && npx lint-staged(frontend) to appease the lint gods
**Original Pull Request:** https://github.com/langgenius/dify/pull/23641 **State:** closed **Merged:** Yes --- ## Summary This PR resolves the issue where JPG files are occasionally displayed as document icons instead of image previews in the `apps/{id}/logs` interface when viewing historical chat records. The root cause was backend file type misclassification being blindly trusted by the frontend. **Problem Analysis:** - Backend `file_factory.py` prioritizes API-specified `type` over detected file type - Frontend `getProcessedFilesFromResponse` directly used backend `type` without validation - Result: Image files incorrectly classified as `type: "document"` display as file icons **Solution - Dual Verification System:** Implemented robust dual verification that validates both filename and MIME type before correcting any classification: ```typescript const detectedTypeFromFileName = getSupportFileType(fileItem.filename, '') const detectedTypeFromMime = getSupportFileType('', fileItem.mime_type) // Only correct when both methods agree AND differ from backend if (detectedTypeFromFileName && detectedTypeFromMime && detectedTypeFromFileName === detectedTypeFromMime && detectedTypeFromFileName \!== fileItem.type) { supportFileType = detectedTypeFromFileName } ``` **Key Features:** - ✅ **Zero Hardcoding**: Uses existing `FILE_EXTS` constants and `getSupportFileType` function - ✅ **Full Type Coverage**: Supports image, video, audio, document, custom file types - ✅ **Conflict Detection**: Prevents false corrections when filename/MIME disagree - ✅ **Backward Compatible**: Correctly classified files remain unchanged - ✅ **TypeScript Safe**: Fixed potential undefined value error **Test Coverage:** - **Total Tests**: 49 test cases (11 new tests for dual verification logic) - **Coverage**: 96.69% statements, 94.04% branches - **Scenarios Tested**: - ✅ Original problem: JPG with document type → corrected to image - ✅ Multi-media support: MP4 video, MP3 audio correction - ✅ Reverse correction: PDF misclassified as image → corrected to document - ✅ Conflict detection: PDF filename + JPG MIME → no change (safety) - ✅ Edge cases: Missing filename/MIME, unknown extensions **Safety Verification:** | Scenario | Filename | MIME Type | Backend Type | Detection Result | Final Type | Action | |----------|----------|-----------|--------------|------------------|------------|---------| | **Original Issue** | image.jpg | image/jpeg | document | image = image | **image** | ✅ Corrected | | **Correct File** | image.jpg | image/jpeg | image | image = image | **image** | ✅ Unchanged | | **Conflict Case** | doc.pdf | image/jpeg | document | document ≠ image | **document** | ✅ Safe: No change | | **Reverse Error** | doc.pdf | application/pdf | image | document = document | **document** | ✅ Corrected | Fixes #23637 ## Screenshots | Before | After | |--------|-------| | JPG files displayed as document icons in logs | JPG files correctly displayed as image thumbnails with preview | ## Checklist - [ ] This change requires a documentation update, included: [Dify Document](https://github.com/langgenius/dify-docs) - [x] I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos\!) - [x] I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change. - [x] I've updated the documentation accordingly. - [x] I ran `dev/reformat`(backend) and `cd web && npx lint-staged`(frontend) to appease the lint gods
yindo added the pull-request label 2026-02-21 20:47:18 -05:00
yindo closed this issue 2026-02-21 20:47:18 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#30335