mirror of
https://github.com/langgenius/dify-official-plugins.git
synced 2026-07-21 17:45:23 -04:00
Gemini with code execution and image return with out correct url #946
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @sweetwxh on GitHub (Jan 22, 2026).
Self Checks
Dify version
1.11.1
Cloud or Self Hosted
Self Hosted (Docker)
Steps to reproduce
I am using Gemini-3-Pro with code execution enabled, allowing it to output Matplotlib charts to render data. However, in the final chat dialog, the image sometimes displays correctly and sometimes does not — for example, the image path appears as sandbox:/mnt/data/medical_aesthetics_analysis.png, and this behavior is highly random. The image returned by the model is actually stored as base64 in inline_data. How is this handled after it reaches Dify? How can I ensure a stable and correct image path in the dialog? Or is there any configuration for this?
✔️ Expected Behavior
URL like this can work:

❌ Actual Behavior
No response
@dosubot[bot] commented on GitHub (Jan 22, 2026):
The root cause is that Dify’s code execution (e.g., Matplotlib in Gemini-3-Pro) runs in a sandbox and returns output as plain stdout—so image paths like
sandbox:/mnt/data/...are not automatically converted to stable URLs or inline images in chat dialogs. Unless the model emits a proper URL or base64 object, you’ll see these internal paths, which aren’t accessible outside the sandbox and lead to inconsistent rendering source.To ensure stable, correct image URLs in chat dialogs, you should convert base64 image data to a file and generate a signed URL using Dify’s file manager. Here’s the recommended workflow source:
Make sure your Docker
.envsetsFILES_URLto an externally accessible address and restart containers after changes. Signed URLs expire quickly for security, so regenerate if longer access is needed.You can also control image rendering with the
MULTIMODAL_SEND_IMAGE_FORMAT(orMULTIMODAL_SEND_FORMAT) config: set to'url'for signed URLs, or'base64'for inline data URIs source.Known limitations: Gemini plugins may not handle multi-turn image generation due to missing
thought_signaturetokens, causing abnormal output after the first image source. For reliable multi-turn image output, consider starting a new conversation for each image or using models/plugins that support inline file handling (e.g.,gemini-3-flash-previewwithuse_inline_fileparameter) source.If you need to render large images, avoid embedding huge base64 strings directly in chat—this can freeze the frontend. Use URLs for safer rendering source.
Let me know if you need more details or code samples for your specific workflow.
To reply, just mention @dosu.
How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other
@sweetwxh commented on GitHub (Jan 23, 2026):
@dosu
Not every time does it end up as
sandbox:/mnt/data/medical_aesthetics_analysis.png; sometimes a correct link is generated, e.g.http://mydify.com/files/tools/17fd9bac-f0b1-4ed5-a600-7f4e7d555653.png?timestamp=1769143497&nonce=9c8d292cd46bd2af1c001055d4181fed&sign=c0qnN56pIdoqoUMCJnn6wF7LYh3nYO3d4ZlwQaIEMpE=.I also looked at the Gemini plugin for Dify. When the model returns an image, the plugin extracts the data, builds an
ImagePromptMessageContentobject, and passes it back. What happens after that, however, is unclear—sometimes it works, sometimes it doesn’t.Here is the relevant snippet from the Gemini plugin:
@dosubot[bot] commented on GitHub (Jan 23, 2026):
After the Gemini plugin returns an ImagePromptMessageContent with base64 image data, Dify tries to persist that image using its ToolFileManager. If the backend receives valid base64 image data, it saves the file and generates a signed URL (like the working example you saw). If it only receives a sandbox path or the upload logic fails (often due to misconfigured FILES_URL or INTERNAL_FILES_URL, or port 5001 not being exposed in Docker), Dify can't generate a URL and just shows the sandbox path instead. This is a known, unresolved bug that affects both self-hosted and cloud setups, and is often triggered by plugin upload failures or missing environment variables.
To ensure consistent image URLs: double-check that both FILES_URL and INTERNAL_FILES_URL are set to externally accessible addresses, port 5001 is exposed in your Docker config, and your images are in a supported format. If you still see sandbox paths, check your logs for file upload or access errors. More details and troubleshooting steps are available in these discussions: file upload config and errors, Docker port exposure, and ToolFileManager logic.
Recent Dify updates also changed how URLs are generated, prioritizing INTERNAL_FILES_URL over FILES_URL, so make sure both are set correctly and restart your containers after any changes PR langgenius/dify#29962, PR langgenius/dify#30598.
If you want a visual, here's the pipeline:
Let me know if you want help interpreting logs or have more questions about your setup.
To reply, just mention @dosu.
How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other
@crazywoola commented on GitHub (Feb 3, 2026):
Hi @sweetwxh, thanks for opening this issue.
Why this is being closed
Dify issue tracking requires English-only issue title and description for consistent collaboration.
Next steps
Please open a new issue in English and include clear details so maintainers can help efficiently.
Thanks for understanding and for your support.