Description
The langgenius/openai_api_compatible plugin fails when invoked from a Dify chatflow LLM node (type llm). The plugin throws PluginInvokeError with Object of type TextPromptMessageContent is not JSON serializable.
The same plugin works correctly for parameter-extractor nodes (type parameter-extractor) when configured with reasoning_mode: prompt, so the issue is specific to how the plugin handles the parts[] multimodal message structure that LLM nodes construct.
Repro steps
- Install plugin
langgenius/openai_api_compatible:0.0.50 in Dify 1.13.x.
- Configure provider pointing to any OpenAI-compatible endpoint (e.g., LiteLLM proxy, Ollama, vLLM):
- Model name:
my-model
- API endpoint:
http://localhost:4000/v1
- API key:
sk-xxx
- Function Call Type: Tool Call
- Vision Support: Not Support
- Create chatflow with at least one
llm node referencing the model.
- Run chatflow with any prompt that includes user input and system prompt template.
Expected
LLM node executes successfully and returns model response.
Actual
Node fails with status exception:
PluginInvokeError: {
"args": {
"description": "[models] Error: Object of type TextPromptMessageContent
is not JSON serializable"
},
"error_type": "InvokeError",
"message": "[models] Error: Object of type TextPromptMessageContent is
not JSON serializable"
}
Important observation: PE nodes work, LLM nodes don't
| Node type |
Result |
parameter-extractor with reasoning_mode: prompt |
✅ works |
parameter-extractor with reasoning_mode: function_call |
❌ different error (related but separate) |
llm regular |
❌ TextPromptMessageContent serialize error |
question-classifier |
❌ (untested but likely same as llm) |
Root cause (hypothesis)
Dify constructs LLM node prompts as multimodal-aware structure (PromptMessage with content: list[PromptMessageContent] where each content has type TextPromptMessageContent). The OpenAI Chat Completions API expects either content: str or content: list[dict] where each dict has type and text fields.
The plugin likely passes the TextPromptMessageContent Python objects directly to json.dumps() without .model_dump() or __dict__ conversion, causing JSON serialization to fail.
PE nodes with reasoning_mode: prompt work because they construct prompts as plain strings (no multimodal wrapping), bypassing the broken serialization path.
Workaround
Use the native vendor-specific plugin (e.g., langgenius/openai/openai, langgenius/anthropic/anthropic, langgenius/gemini/google) directly for LLM-type nodes. The OpenAI-API-compatible plugin is currently usable only for parameter-extractor nodes with reasoning_mode: prompt.
In our production setup we ended up with a hybrid strategy:
- PE nodes → OpenAI-API-compatible plugin → LiteLLM proxy → multi-vendor fallback (works)
- LLM nodes (formatters, classifier) → direct vendor plugins (workaround) (works)
Suggested fix
In the plugin's request builder, before serializing message content to JSON, convert TextPromptMessageContent (and any other PromptMessageContent subclass) to dict via .model_dump() (if pydantic) or explicit conversion:
def _serialize_content(content):
if isinstance(content, str):
return content
if isinstance(content, list):
return [{"type": c.type, "text": c.data} for c in content]
return content
Environment
- Dify: v1.13.1
- Plugin:
langgenius/openai_api_compatible:0.0.50
- Plugin daemon:
langgenius/dify-plugin-daemon:main-local
- Backend endpoint: LiteLLM Proxy v1.85.0 (OpenAI-compatible API)
- Affected node types:
llm, likely question-classifier
Impact
Currently the plugin is only usable for PE nodes. Any team trying to use LiteLLM (or any OpenAI-compatible proxy/server) as their unified model gateway for ALL chatflow nodes (the natural use case for this plugin) cannot do so until this is fixed.
Description
The
langgenius/openai_api_compatibleplugin fails when invoked from a Dify chatflow LLM node (typellm). The plugin throwsPluginInvokeErrorwithObject of type TextPromptMessageContent is not JSON serializable.The same plugin works correctly for parameter-extractor nodes (type
parameter-extractor) when configured withreasoning_mode: prompt, so the issue is specific to how the plugin handles theparts[]multimodal message structure that LLM nodes construct.Repro steps
langgenius/openai_api_compatible:0.0.50in Dify 1.13.x.my-modelhttp://localhost:4000/v1sk-xxxllmnode referencing the model.Expected
LLM node executes successfully and returns model response.
Actual
Node fails with status
exception:Important observation: PE nodes work, LLM nodes don't
parameter-extractorwithreasoning_mode: promptparameter-extractorwithreasoning_mode: function_callllmregularquestion-classifierllm)Root cause (hypothesis)
Dify constructs LLM node prompts as multimodal-aware structure (PromptMessage with
content: list[PromptMessageContent]where each content has typeTextPromptMessageContent). The OpenAI Chat Completions API expects eithercontent: strorcontent: list[dict]where each dict hastypeandtextfields.The plugin likely passes the
TextPromptMessageContentPython objects directly tojson.dumps()without.model_dump()or__dict__conversion, causing JSON serialization to fail.PE nodes with
reasoning_mode: promptwork because they construct prompts as plain strings (no multimodal wrapping), bypassing the broken serialization path.Workaround
Use the native vendor-specific plugin (e.g.,
langgenius/openai/openai,langgenius/anthropic/anthropic,langgenius/gemini/google) directly for LLM-type nodes. The OpenAI-API-compatible plugin is currently usable only forparameter-extractornodes withreasoning_mode: prompt.In our production setup we ended up with a hybrid strategy:
Suggested fix
In the plugin's request builder, before serializing message content to JSON, convert
TextPromptMessageContent(and any otherPromptMessageContentsubclass) to dict via.model_dump()(if pydantic) or explicit conversion:Environment
langgenius/openai_api_compatible:0.0.50langgenius/dify-plugin-daemon:main-localllm, likelyquestion-classifierImpact
Currently the plugin is only usable for PE nodes. Any team trying to use LiteLLM (or any OpenAI-compatible proxy/server) as their unified model gateway for ALL chatflow nodes (the natural use case for this plugin) cannot do so until this is fixed.