langgenius/dify · error
Unsupported Media Type
Error message
Unsupported Media Type
What it means
HTTP 415 Unsupported Media Type from the RAG pipeline draft-workflow sync endpoint. The handler inspects `request.headers["Content-Type"]`: only `application/json` (parsed via `console_ns.payload`) and `text/plain` (parsed via `model_validate_json(request.data)`) are accepted; any other Content-Type triggers `abort(415)` with the default message.
Source
Thrown at api/controllers/console/datasets/rag_pipeline/rag_pipeline_workflow.py:234
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@console_ns.expect(console_ns.models[DraftWorkflowSyncPayload.__name__])
@console_ns.response(200, "Success", console_ns.models[RagPipelineWorkflowSyncResponse.__name__])
def post(self, current_user: Account, pipeline: Pipeline):
"""
Sync draft workflow
"""
content_type = request.headers.get("Content-Type", "")
if "application/json" in content_type:
payload_dict = console_ns.payload or {}
payload = DraftWorkflowSyncPayload.model_validate(payload_dict)
elif "text/plain" in content_type:
try:
payload = DraftWorkflowSyncPayload.model_validate_json(request.data)
except (ValueError, ValidationError):
return {"message": "Invalid JSON data"}, 400
else:
abort(415)
rag_pipeline_service = RagPipelineService(db.session())
try:
environment_variables_list = Workflow.normalize_environment_variable_mappings(
payload.environment_variables or [],
)
environment_variables = [
variable_factory.build_environment_variable_from_mapping(obj) for obj in environment_variables_list
]
conversation_variables_list = payload.conversation_variables or []
conversation_variables = [
variable_factory.build_conversation_variable_from_mapping(obj) for obj in conversation_variables_list
]
workflow = rag_pipeline_service.sync_draft_workflow(
pipeline=pipeline,
graph=payload.graph,
unique_hash=payload.hash,
account=current_user,View on GitHub (pinned to ef8544b173)
Solutions
- Set `Content-Type: application/json` and send a JSON body matching `DraftWorkflowSyncPayload`.
- If streaming a raw JSON string, use `Content-Type: text/plain` and ensure the body is valid JSON parseable by `DraftWorkflowSyncPayload.model_validate_json`.
- Do not use `FormData`/`multipart` for this route — it expects a single JSON document.
- Verify no intermediary (gateway, SDK) rewrites the Content-Type.
Example fix
// before
fetch(url, { method: 'PUT', body: new FormData(form) })
// after
fetch(url, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}) Defensive patterns
Strategy: validation
Validate before calling
def ok_content_type(ct: str | None) -> bool:
ct = (ct or "").lower()
return "application/json" in ct or "text/plain" in ct
headers = {"Content-Type": "application/json"}
assert ok_content_type(headers["Content-Type"]) Type guard
ALLOWED = ("application/json", "text/plain")
def is_allowed_content_type(ct: str | None) -> bool:
return any(a in (ct or "").lower() for a in ALLOWED) Try / catch
try:
resp = client.put(url, json=payload, headers={"Content-Type": "application/json"})
except HTTPError as err:
if err.response.status_code == 415:
# switch to JSON body and retry
...
elif err.response.status_code == 400:
# text/plain body failed model_validate_json
...
raise Prevention
- Always set Content-Type: application/json for this route.
- Do not use FormData/multipart here.
- Verify no gateway rewrites Content-Type.
- For text/plain, ensure the body is valid JSON parseable by DraftWorkflowSyncPayload.
When it happens
Trigger: POST/PUT to the draft-workflow sync route with a Content-Type other than `application/json` or `text/plain` — e.g. `multipart/form-data`, `application/x-www-form-urlencoded`, missing Content-Type, or a Content-Type with an unexpected main type.
Common situations: Client using `FormData` instead of JSON; curl/Postman defaulting to `application/x-www-form-urlencoded`; SDK that auto-sets `multipart/form-data` for large payloads; reverse proxy stripping Content-Type.
Related errors
- The server does not support the media type transmitted in th
- usage_missing_arg
- not_logged_in
- usage_missing_arg
- usage_invalid_flag
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/fda060df24283c3f.
Report an issue: GitHub.