Skip to content

1.14.0-rc1: Skill creation fails on UI (CORS to api:5001) but creates a ghost record, leading to 500 FileNotFoundError upon editing #32816

@shuo1104

Description

@shuo1104

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

Version1.14.0-rc1

Cloud or Self Hosted

Self Hosted (Docker)

Steps to reproduce

The following is from my AI assistant:

Description:
In version 1.14.0-rc1 (Docker Compose deployment), creating a new Skill fails due to network/CORS errors on the frontend, but a database record is still created without rolling back. Because the physical skill.md file is never written to the OpenDAL storage, attempting to edit this "ghost" Skill subsequently triggers a 500 Internal Server Error (FileNotFoundError) in the API.

Steps to Reproduce:

  1. Deploy Dify 1.14.0-rc1 using the default Docker Compose configuration.
  2. Navigate to the frontend and attempt to create a new Skill.
  3. Observe that the UI indicates a creation failure. The browser console shows CORS errors attempting to reach the internal Docker hostname (http://api:5001).
  4. Notice that despite the UI failure, the Skill appears in the workspace list (database record was created).
  5. Click on the newly created Skill to edit it (skill.md).
  6. A 500 Internal Server Error occurs.

Expected Behavior:

  1. The frontend should use the correct external API URL, not the internal container address (http://api:5001).
  2. If the physical file fails to be created/uploaded via OpenDAL, the database transaction should be rolled back so no "ghost" Skill appears in the list.
  3. File writing to local storage using OpenDAL should succeed with default configurations.

Actual Behavior / Root Causes Identified:

1. Frontend CORS Error (Calling internal Docker hostname):
During Skill creation, the frontend attempts to call http://api:5001 directly instead of routing through the Nginx proxy (localhost or domain), leading to a CORS block:

Access to XMLHttpRequest at 'http://api:5001/files/storage-files/4c31630a-566d-4f84-aa4e-04b6fd62e7cd' from origin 'http://localhost' has been blocked by CORS policy...
net::ERR_FAILED

2. Missing Database Rollback:
Because the file upload/creation fails, the API throws an error to the frontend, but the initial database record for the Skill remains.

3. API 500 Error (OpenDAL File Not Found):
When attempting to open the ghost Skill, the API correctly looks for the file but OpenDAL throws a FileNotFoundError because it was never saved:

  # ... (Traceback omitted for brevity) ...
  File "/app/api/services/app_asset_service.py", line 226, in get_file_content
    return asset_storage.load_once(key)
  File "/app/api/extensions/storage/opendal_storage.py", line 49, in load_once
    raise FileNotFoundError("File not found")
FileNotFoundError: File not found

Environment:

  • Dify Version: 1.14.0-rc1
  • Deployment: Docker Compose
  • Storage: STORAGE_TYPE=opendal, OPENDAL_SCHEME=fs, OPENDAL_FS_ROOT=storage

Troubleshooting Already Performed (For Maintainers' Reference):

  • Permissions: Executed chmod -R 777 volumes/ on the host machine. The issue persists, confirming the file is genuinely not being written, rather than just a permission block on read.
  • Pathing: Changed OPENDAL_FS_ROOT to an absolute path (/app/api/storage) in .env. Did not resolve the issue.
  • WebSocket Fix: Initially encountered The gevent-websocket server is not configured appropriately upon clicking the Skill. Fixed this by manually adding SERVER_WORKER_CLASS: geventwebsocket.gunicorn.workers.GeventWebSocketWorker to the api service in docker-compose.yaml (Might be another missing default config in rc1).
  • Worker Logs: Checked worker container logs during creation; no errors were thrown there, indicating the failure is synchronous in the API/Frontend interaction.
Image Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions