Skip to content

error with m.get("role") when the message is a json #460

Closed

Description

@BadWolf-63

little problem with the management of json messages. Here the fix:

`def openai_to_messages(req: dict) -> tuple[list[dict], list[dict] | None, dict]:
"""OpenAI Chat Completions -> (template messages, template tools, template kwargs)."""
messages = []

raw = req.get("messages", [])
if isinstance(raw, str):
    try:
        raw = json.loads(raw)      # client double-encoded messages as a JSON string
    except ValueError:
        raw = []
if not isinstance(raw, list):
    raw = []                       # dict / number / None -> nothing to iterate
for m in raw:

# for m in req.get("messages", []):
    role = m.get("role")
    if role == "developer":
        role = "system"
    out = {"role": role, "content": _parts_of(m.get("content")) if role in ("user", "tool", "assistant") else _text_of(m.get("content"))}
    if m.get("reasoning_content"):
        out["reasoning_content"] = m["reasoning_content"]
    if m.get("tool_calls"):
        calls = []
        for c in m["tool_calls"]:
            if not isinstance(c, dict):
                continue
            fn = c.get("function", c)
            args = fn.get("arguments")
            if isinstance(args, str):               # the template requires a mapping, not a JSON string
                args = json.loads(args) if args.strip() else {}
            calls.append({"function": {"name": fn.get("name"), "arguments": args or {}}})
        out["tool_calls"] = calls
    messages.append(out)
tools = [t.get("function", t) if isinstance(t, dict) and t.get("type") == "function" else t
         for t in req.get("tools") or []] or None
kwargs = {}
# OpenAI Chat Completions: "reasoning_effort"; Responses style: "reasoning": {"effort": ...}
reasoning = req.get("reasoning") if isinstance(req.get("reasoning"), dict) else {}
kwargs.update(effort_kwargs(req.get("reasoning_effort") or reasoning.get("effort")))
# the vLLM / llama.cpp convention: {"chat_template_kwargs": {"enable_thinking": false, "reasoning_effort": "low"}}
for k, v in (req.get("chat_template_kwargs") or {}).items():
    if k == "enable_thinking" and not v:
        kwargs = {"enable_thinking": False}
    elif k == "reasoning_effort" and "enable_thinking" not in kwargs:
        kwargs.update(effort_kwargs(v))
return _late_system_to_user(messages), tools, kwargs

`

Activity

  1. Niko1221 commented on Oct 2, 2026

    @Niko1221
    Owner

    Fixed in 0.1.35: messages sent as a JSON string is decoded, and a list with non-object entries gets a 400 with a clear message. Both APIs, with tests. Thanks for the patch! Run START-HERE.bat (Linux: ./setup.sh) once to update.

  2. added a commit that references this issue on Oct 2, 2026
    d9ab843
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions