Skip to content

[Bug] openai_api_compatible plugin fails serialize TextPromptMessageContent in LLM-type nodes #3111

@alejandro-xux

Description

@alejandro-xux

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

  1. Install plugin langgenius/openai_api_compatible:0.0.50 in Dify 1.13.x.
  2. 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
  3. Create chatflow with at least one llm node referencing the model.
  4. 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.


Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions