Skip to content

X provider uploads GIF bytes labelled with the original file's mime type #2018

Description

@pamelaromeroo

X provider uploads GIF bytes labelled with the original file's mime type

Version: v1.47.0 (self-hosted, Docker)

What happens

In x.provider.ts, uploadMedia converts every non-mp4 input to GIF, but derives media_type from the original filename:

client.v2.uploadMedia(
  m.path.indexOf('mp4') > -1
    ? Buffer.from(await readOrFetch(m.path))
    : await sharp(await readOrFetch(m.path), {
        animated: lookup(m.path) === 'image/gif',
      })
        .resize({ width: 1000 })
        .gif()
        .toBuffer(),
  {
    media_type: lookup(m.path), // <- original extension, not the converted format
  },
)

For a .png input the uploaded bytes are GIF while media_type is declared as image/png. The two only agree when the source file is already a .gif.

Evidence, and its limits

This was identified by reading the code — not confirmed to cause a specific upload failure.

Our account hit 402 Payment Required (pay-per-use credits depleted) on the v2 media endpoint before the mismatch could be isolated, so I can't honestly attribute any failure we saw to it. Filing as a code-correctness issue rather than a reproduced bug.

Suggested fix

Set the declared type to match what was actually produced:

const isVideo = m.path.indexOf('mp4') > -1;
const buffer = isVideo
  ? Buffer.from(await readOrFetch(m.path))
  : await sharp(/* ... */).gif().toBuffer();

client.v2.uploadMedia(buffer, {
  media_type: isVideo ? lookup(m.path) : 'image/gif',
});

Alternatively, skip the conversion for still images and pass the original bytes and type straight through.

Related observation

Converting every still image to GIF and downscaling to 1000px wide is lossy for a static PNG or JPEG — 256 colours and a smaller raster than X accepts. That may well be deliberate (uniform handling for animated inputs), but it is surprising for a plain image post, and worth a comment in the source if intended.

Activity

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions