hiyouga/LlamaFactory · error · HTTPException

Invalid input type {input_item.type}.

Error message

Invalid input type {input_item.type}.

What it means

Raised as HTTP 400 during request preprocessing when a message's content is a list and one of its items has a type other than the supported multimodal types (text, image_url, video_url, audio_url). The endpoint iterates content parts and only handles those four types; anything else (e.g. 'file', 'input_audio', or a typo) is rejected.

Source

Thrown at src/llamafactory/api/chat.py:161

                        check_ssrf_url(video_url)
                        video_stream = requests.get(video_url, stream=True).raw

                    videos.append(video_stream)
                elif input_item.type == "audio_url":
                    text_content += AUDIO_PLACEHOLDER
                    audio_url = input_item.audio_url.url
                    if re.match(r"^data:audio\/(mpeg|mp3|wav|ogg);base64,(.+)$", audio_url):  # base64 audio
                        audio_stream = io.BytesIO(base64.b64decode(audio_url.split(",", maxsplit=1)[1]))
                    elif os.path.isfile(audio_url):  # local file
                        check_lfi_path(audio_url)
                        audio_stream = audio_url
                    else:  # web uri
                        check_ssrf_url(audio_url)
                        audio_stream = requests.get(audio_url, stream=True).raw

                    audios.append(audio_stream)
                else:
                    raise HTTPException(
                        status_code=status.HTTP_400_BAD_REQUEST, detail=f"Invalid input type {input_item.type}."
                    )

            input_messages.append({"role": ROLE_MAPPING[message.role], "content": text_content})
        else:
            input_messages.append({"role": ROLE_MAPPING[message.role], "content": message.content})

    tool_list = request.tools
    if isinstance(tool_list, list) and len(tool_list):
        try:
            tools = json.dumps([dictify(tool.function) for tool in tool_list], ensure_ascii=False)
        except json.JSONDecodeError:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid tools")
    else:
        tools = None

    return input_messages, system, tools, images or None, videos or None, audios or None

View on GitHub (pinned to f28afaf635)

Solutions

  1. Remove or replace unsupported content parts; only 'text', 'image_url', 'video_url', 'audio_url' are accepted.
  2. If you intended audio, use {type: 'audio_url', audio_url: {url: ...}} rather than 'input_audio'.
  3. Add a client-side filter over message.content lists to drop non-supported types before posting.
  4. Check this repo's chat.py content-part loop for the canonical accepted shapes if unsure.

Example fix

// before
content: [
  {type: 'text', text: 'describe this'},
  {type: 'input_audio', input_audio: {data: '...', format: 'wav'}}
]
// after
content: [
  {type: 'text', text: 'describe this'},
  {type: 'audio_url', audio_url: {url: 'data:audio/wav;base64,...'}}
]
Defensive patterns

Strategy: validation

Validate before calling

ALLOWED = {"text", "image_url", "video_url", "audio_url"}
def valid_content_parts(messages):
    for m in messages:
        if isinstance(m.get("content"), list):
            for part in m["content"]:
                if part.get("type") not in ALLOWED:
                    return False
    return True

Type guard

const ALLOWED = new Set(['text', 'image_url', 'video_url', 'audio_url']);
const hasValidContentParts = (msgs) => msgs.every(m =>
  typeof m.content === 'string' ||
  (Array.isArray(m.content) && m.content.every(p => ALLOWED.has(p.type)))
);

Try / catch

catch (e) { if (e.status === 400 && e.detail?.startsWith('Invalid input type')) { const bad = /* find part not in ALLOWED */; body = stripPart(body, bad); retry once; } else throw e; }

Prevention

When it happens

Trigger: POST /v1/chat/completions with content: [{type: 'file_url', ...}] or [{type: 'text', text: 'hi'}, {type: 'emoji', ...}]; sending OpenAI's newer 'input_audio' type instead of 'audio_url'; a client SDK that emits an unsupported content-part schema.

Common situations: Upgrading a client library that changed content-part type names; copying payloads from OpenAI docs that include types LlamaFactory does not implement; hand-built JSON payloads with a typo in the type field.

Related errors


AI-assisted analysis of hiyouga/LlamaFactory@f28afaf635 (2026-08-14). Data as JSON: /api/errors/75f535931ad55feb. Report an issue: GitHub.