dify - 💡(How to fix) Fix Chatflow file validation fails on memory replay when allowed_file_types is [custom]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

The exception is ValueError("File validation failed for file: <name>.png") raised at api/factories/file_factory/builders.py:51.

Root Cause

Root cause

Code Example

Run Failed: File validation for file: <name>.png

---

if (
    config.allowed_file_types
    and input_file_type not in config.allowed_file_types
    and input_file_type != FileType.CUSTOM   # only the literal-CUSTOM bypass
):
    return False
RAW_BUFFERClick to expand / collapse

Self Checks

  • I have read the Contributing Guide and Language Policy.
  • This is only for bug report, if you would like to ask a question, please head to Discussions.
  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit this report, otherwise it will be closed.
  • 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
  • Please do not modify this template :) and fill in all the required fields.

Dify version

Enterprise 3.7.3 (also reproduces on main, commit 1e2d309122).

Cloud or Self Hosted

Self Hosted (Docker), Self Hosted (Source), Cloud

Steps to reproduce

  1. Create a Chatflow: Start → LLM → End.
  2. Open the LLM node and enable Memory.
  3. Features → File Upload → enable.
  4. Set Allowed File Type to "Other file types" (custom) and add .png to the custom-extension list.
  5. Publish and open the Web App / Preview.
  6. Round 1 — upload a .png image with any question → response is returned normally.
  7. Round 2 — send a follow-up question without uploading anything → fails.

✔️ Expected Behavior

Round 2 should succeed. A file that passed validation when it was first uploaded should continue to pass when replayed from conversation history, as long as the workflow's file_upload configuration is unchanged.

❌ Actual Behavior

Round 2 fails with:

Run Failed: File validation for file: <name>.png

The exception is ValueError("File validation failed for file: <name>.png") raised at api/factories/file_factory/builders.py:51.

Root cause

is_file_valid_with_config (api/factories/file_factory/validation.py:20-25) special-cases input_file_type == FileType.CUSTOM, but not the case where config.allowed_file_types contains CUSTOM as a fallback bucket:

if (
    config.allowed_file_types
    and input_file_type not in config.allowed_file_types
    and input_file_type != FileType.CUSTOM   # only the literal-CUSTOM bypass
):
    return False
  • Round 1 — the front-end posts mapping["type"] = "custom", so the bypass triggers and the file passes. _resolve_file_type (builders.py:103-114) then coerces the custom-slot upload to its detected type — for a PNG that's FileType.IMAGE. MessageFile.type is persisted as the resolved type at core/app/apps/message_based_app_generator.py:227 (type=file.type).
  • Round 2TokenBufferMemory.get_history_prompt_messages rebuilds the file via build_from_message_file, which sets mapping["type"] = message_file.type = "image" (api/factories/file_factory/message_files.py:43). The validator now sees input_file_type = "image", the literal-CUSTOM bypass no longer triggers, and the file is rejected — even though both the file and the workflow config are unchanged.

The "I came from a custom slot" intent is lost across the round-trip because MessageFile.type only records the resolved type.

Affected modes

  • ADVANCED_CHAT (Chatflow) — primary report
  • CHAT, AGENT_CHAT — same TokenBufferMemory._build_prompt_message_with_files path (api/core/memory/token_buffer_memory.py:90-98)
  • LLM / Question Classifier / Parameter Extractor / Agent nodes inside a Chatflow when memory is enabled (api/core/workflow/node_factory.py:240)
  • Basic Agent mode also calls build_from_message_files(config=...) over history (api/core/agent/base_agent_runner.py:532) — same bug

Not affected: WORKFLOW, COMPLETION, webhook/schedule triggers — no memory replay.

Secondary issue (same trigger point)

validation.py:30's extension-whitelist comparison is a raw in — neither case- nor dot-insensitive. services/file_service.py:60 already lowercases and strips the dot from the upload side, so File.extension is always .<lower>. A user-defined whitelist containing .PNG (or png, or any other inconsistent form) cannot match. The module already case-normalizes its built-in extension sets via _with_case_variants (graphon/file/constants.py:9-11); the user-defined whitelist path missed that precedent. This surfaces as the same ValueError at the same line, but triggers on round 1 rather than round 2 (so it's reachable independently of the memory replay bug).

Suggested fix direction

  1. In is_file_valid_with_config — bypass the type-bucket check whenever FileType.CUSTOM in config.allowed_file_types (not only when input_file_type is literal CUSTOM). Normalize extensions on both sides of the comparison (case- and dot-insensitive).
  2. In TokenBufferMemory._build_prompt_message_with_files and core/agent/base_agent_runner.py:532 — pass config=None when rebuilding files from conversation history. This aligns with the existing pattern in api/models/utils/file_input_compat.py:200, where build_file_from_stored_mapping rehydrates Message.inputs payloads without re-running validation. Replay should not re-validate; validation belongs at upload time.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING