Skip to content

bug(channels): Telegram image media_type is application/octet-stream — breaks vision #528

@f-liva

Description

@f-liva

Bug Description

Photos sent via Telegram are downloaded and base64-encoded correctly, but the media_type is set to application/octet-stream instead of the actual image type (e.g. image/jpeg). This causes LLM providers to reject the image content, as they require a valid image MIME type.

Regression

This was supposed to be fixed as part of issue #362 and the related PR #365. The Telegram parsing and bridge download pipeline was added, but the media type detection has a bug that silently breaks vision.

Root Cause

In crates/openfang-channels/src/bridge.rs, download_image_to_blocks() (line ~818):

let content_type = resp
    .headers()
    .get("content-type")
    .and_then(|v| v.to_str().ok())
    .map(|ct| ct.split(';').next().unwrap_or(ct).trim().to_string());

let media_type = content_type.unwrap_or_else(|| {
    // fallback to URL extension detection
    ...
});

The code trusts the Content-Type header from Telegram's file download API. However, Telegram returns application/octet-stream for all file downloads via getFile. Since the header IS present (just wrong), the URL-extension fallback never runs.

The result: ContentBlock::Image { media_type: "application/octet-stream", data: "..." } is sent to the LLM, which rejects it because application/octet-stream is not a valid image MIME type.

Evidence

Session logs show: [image: application/octet-stream] — confirming the image data arrives but with wrong MIME type.

Proposed Fix

  1. If Content-Type is application/octet-stream or another non-image type, fall through to secondary detection
  2. Add magic-byte detection (JPEG FF D8, PNG 89 50 4E 47, etc.) as the most reliable method
  3. Keep URL extension as tertiary fallback

Environment

  • OpenFang v0.3.46
  • Channel: Telegram (polling mode)
  • LLM: qwen-plus (OpenAI-compatible API)

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions