2026-06-22 OWUI Images Rendering Twice
Context: Working on dotfiles (.config, branch main).
What I set out to do
Figure out why generated images were displaying twice in Open WebUI, using two recent chats as evidence: “🏗️ OpenRouter LiteLLM Stack” and ”🍓 Strawberry Bed Build Infographic”.
What I actually did
Read the actual stored chats out of webui.db (the chat table, parsing history.messages.*) rather than theorizing. Found the image was registered through two channels that OWUI never dedupes:
- OpenRouter chat — the
generate_imagebuiltin tool attaches the image tomessage.filesand returns its/api/v1/files/<id>/contenturl to the model with a “don’t embed again” instruction. The model (DeepSeek V4 Flash orchestrator) ignored that and re-embedded it as markdown → attachment + markdown = twice. - Strawberry chat (
gpt-5-image, inlinedelta.images) — the same file id landed inmessage.filestwice.add_message_files_by_id_and_message_iddoesmessage_files + fileswith no dedup (models/chats.py), andupload_file_handlermints a fresh id per upload, so a repeated id means the same entry was appended twice.
Wrote two fixes into the existing boot-time patcher owui_image_cost_patch.py: strip the url from the two builtin emitter-returns (model can’t paste back what it never sees), and dedupe the files list by url. Dry-ran the patcher against the live container, hm switch (recreated the container, all 9 patches re-applied clean), just check green, committed as 2288145.
Then ran a live test through the browser: asked DeepSeek to generate a red circle. The tool fired (“Explored generate_image”), the model replied with only an acknowledgment, and the DB row showed 1 files entry, 0 markdown images — and the tool output to the model no longer carried the url. Cost folding still intact (3 calls, $0.07).
What was striking
- The bug was two genuinely different mechanisms producing the same symptom; only reading the real DB rows separated them. Theorizing alone would have conflated them.
- The “don’t embed again” prompt instruction was never going to be reliable — the real fix is to withhold the url so re-embedding is impossible. Defaults over politeness.
add_message_filesdoing blind concatenation with no dedup is the structural root cause that makes any double-write visible.
Related
- 2026-06-22 OWUI Per-Message Cost Tracking — same
owui_image_cost_patch.pypatcher - 2026-06-22 OWUI Mobile Image Download
- 2026-06-21 Open WebUI Image Models On Demand