Skip to content

MessagesSendMultiMedia returns rpc error code 400: MEDIA_INVALID when sending multiple media in a single post #1527

Closed

Description

@asadbekGo

I am trying to send multiple media files (e.g., images) in a single post using MessagesSendMultiMedia, but I keep getting the error:
rpc error code 400: MEDIA_INVALID

_, err = v1.tgBot.Client.API().MessagesSendMultiMedia(context.Background(), &tg.MessagesSendMultiMediaRequest{
Peer: &tg.InputPeerChat{ChatID: groupId},
MultiMedia: []tg.InputSingleMedia{
{
Media: &tg.InputMediaUploadedPhoto{File: inputFile},
RandomID: rand.Int63(),
Message: post.Text,
},
{
Media: &tg.InputMediaUploadedPhoto{File: inputFile},
RandomID: rand.Int63(),
},
},
})

What I Tried:

  1. Verified that inputFile is correctly uploaded and contains valid ID, Parts, and MD5Checksum.
  2. Ensured &inputFile is correctly assigned (also tried inputFile without pointer).
  3. Tried InputMediaUploadedDocument instead of InputMediaUploadedPhoto (same error).
  4. Attempted adding Flags: 1, but GroupedID is not available in InputSingleMedia.
    Questions:
  5. How can I send multiple media files in a single post instead of separate messages?
  6. Is there a way to properly group media items using MessagesSendMultiMedia?
  7. Does InputSingleMedia support GroupedID, or is there another approach?
    Would appreciate any insights or suggestions. Thanks!

Activity

  1. asadbekGo commented on Mar 11, 2025

    @asadbekGo
    Author
  2. borzovplus commented on Mar 11, 2025

    @borzovplus
    Contributor

    before using MessagesSendMultiMedia you should upload all files to telegram, please check docs before creating a issue https://core.telegram.org/methods

  3. asadbekGo commented on Mar 11, 2025

    @asadbekGo
    Author

    @borzovplus I checked this and studied the documentation, but I still face the same problem. Have you tried using multiMedia yourself, if you know, can you please show me?

  4. borzovplus commented on Mar 11, 2025

    @borzovplus
    Contributor

    I can not to show, because I have a lot of abstractions (to much codes).
    Try use "github.com/gotd/td/telegram/uploader" to upload Media before call MessagesSendMultiMedia, than create []tg.InputSingleMedia with uploaded medias

  5. asadbekGo commented on Mar 12, 2025

    @asadbekGo
    Author

    func UploadFile(ctx context.Context, client *telegram.Client, filePath string) (tg.InputFileClass, []byte, error) {
    file, err := os.Open(filePath)
    if err != nil {
    return nil, nil, fmt.Errorf("error opening file: %w", err)
    }
    defer file.Close()

    fileInfo, err := file.Stat()
    if err != nil {
    	return nil, nil, fmt.Errorf("error getting file info: %w", err)
    }
    
    if fileInfo.Size() > maxFileSize {
    	return nil, nil, fmt.Errorf("file size exceeds the limit of %d bytes", maxFileSize)
    }
    
    fileBytes, err := io.ReadAll(file)
    if err != nil {
    	return nil, nil, fmt.Errorf("error reading file: %w", err)
    }
    
    upl := uploader.NewUploader(client.API()).WithPartSize(uploader.MaximumPartSize)
    
    f, err := upl.FromPath(context.Background(), filePath)
    if err != nil {
    	return nil, nil, fmt.Errorf("error creating uploader from path: %w", err)
    }
    
    return f, fileBytes, nil
    

    }

    @borzovplus Yes, I am using the same uploader package, but still no result.

  6. shampigeon commented on Mar 22, 2025

    @shampigeon

    Have you found a solution? @asadbekGo

  7. asadbekGo commented on Mar 22, 2025

    @asadbekGo
    Author

    no, I still haven't found a solution. If you know a solution, please help @shampigeon

  8. asadbekGo commented on Apr 9, 2025

    @asadbekGo
    Author

    please help @ernado

  9. meder111 commented on May 19, 2025

    @meder111

    Привет @asadbekGo нашел решение ?

  10. asadbekGo commented on Jul 2, 2025

    @asadbekGo
    Author

    @meder111 Привет, пока не нашел

  11. fauxlevin commented on May 2, 2026

    @fauxlevin

    To make it work you should:
    Step 1: Upload all media by calling MessagesUploadMedia() and use InputMediaUploadedPhoto type as media.
    Step 2: Parse responses to build InputMediaPhoto type for every media
    Step 3: Finally call MessagesSendMultiMedia and use InputMediaPhoto as a media type from step 2.

    Looks like this, removed some error handling from the code.

    multimedia := make([]tg.InputSingleMedia, 0, len(images))
    
    for i := range images {
    	resp, err := api.MessagesUploadMedia(ctx, &tg.MessagesUploadMediaRequest{
    		Peer:  outputPeer,
    		Media: &tg.InputMediaUploadedPhoto{
    			File: images[i],
    		},
    	})
    	mediaPhoto := resp.(*tg.MessageMediaPhoto)
    	photo := mediaPhoto.Photo.(*tg.Photo)
    	multimedia = append(multimedia, tg.InputSingleMedia{
    		Media: &tg.InputMediaPhoto{
    			ID: &tg.InputPhoto{
    				ID:            photo.ID,
    				AccessHash:    photo.AccessHash,
    				FileReference: photo.FileReference,
    			},
    		},
    		RandomID: rand.Int63()
    	})
    }
    _, err := api.MessagesSendMultiMedia(ctx, &tg.MessagesSendMultiMediaRequest{
    	Peer:       outputPeer,
    	MultiMedia: multimedia,
    })

    Figured it out from this comment: alik0211/mtproto-core#148 (comment)

  12. expary commented on Jun 8, 2026

    @expary
    Contributor

    For messages.sendMultiMedia, Telegram does not accept raw inputMediaUploaded* constructors directly in multi_media. The official docs now state this explicitly:

    The medias to send: note that they must be separately uploaded using messages.uploadMedia first, using raw inputMediaUploaded* constructors is not supported.

    Reference: https://core.telegram.org/method/messages.sendMultiMedia

    So this will fail with MEDIA_INVALID:

    tg.InputSingleMedia{
        Media: &tg.InputMediaUploadedPhoto{File: inputFile},
    }

    The media has to be uploaded/associated first, then converted to an InputMediaPhoto or InputMediaDocument and passed to messages.sendMultiMedia.

    If you use the higher-level telegram/message helpers, gotd already handles this flow for uploaded photos/documents in album mode:

    sender := message.NewSender(api).Resolve(peer)
    
    _, err := sender.Album(ctx,
        message.UploadedPhoto(file1, message.Text("first caption")),
        message.UploadedPhoto(file2),
    )

    Internally, message.UploadedPhoto(...).applyMulti calls messages.uploadMedia, converts the returned MessageMediaPhoto into InputMediaPhoto, and then Album sends it through messages.sendMultiMedia.

    If using the raw generated API, the flow should look like this:

    media := make([]tg.InputSingleMedia, 0, len(files))
    
    for _, file := range files {
        uploaded, err := api.MessagesUploadMedia(ctx, &tg.MessagesUploadMediaRequest{
            Peer: peer,
            Media: &tg.InputMediaUploadedPhoto{
                File: file,
            },
        })
        if err != nil {
            return err
        }
    
        photoMedia, ok := uploaded.(*tg.MessageMediaPhoto)
        if !ok {
            return fmt.Errorf("unexpected media type %T", uploaded)
        }
        photo, ok := photoMedia.Photo.AsNotEmpty()
        if !ok {
            return fmt.Errorf("unexpected empty photo")
        }
    
        media = append(media, tg.InputSingleMedia{
            Media: &tg.InputMediaPhoto{
                ID: photo.AsInput(),
            },
            RandomID: rand.Int63(),
        })
    }
    
    _, err := api.MessagesSendMultiMedia(ctx, &tg.MessagesSendMultiMediaRequest{
        Peer:       peer,
        MultiMedia: media,
    })

    No GroupedID is needed on InputSingleMedia; Telegram groups the items because they are sent in one messages.sendMultiMedia call.

  13. expary commented on Jun 8, 2026

    @expary
  14. expary commented on Jun 8, 2026

    @expary
  15. expary commented on Jun 8, 2026

    @expary
  16. expary commented on Jun 8, 2026

    @expary
  17. locked and limited conversation to collaborators on Jun 15, 2026
  18. converted this issue into a discussion #1787 on Jun 15, 2026
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

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions