PDF Document Processing returns Bad Request

Hi,

I’m working on a Node JS Api, and I m trying to use The Gemini API to process a pdf file. No matter what I do I always get "error": "[GoogleGenerativeAI Error]: Error fetching from https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent: [400 Bad Request] Request contains an invalid argument."

For example, I added some logs as you will see in the code below and I see to get the correct values:

Input body:

{
    "pdfUrl": "https://www.mv.org/cms/lib/PA02218547/Centricity/Domain/107/Module%2011.pdf"
}

Downloaded and saved PDF as: /var/folders/f2/7yxklcss0yb5bzxmpw31yz_m0000gn/T/tmp-25771-g9NDJZO1p6uS-.pdf, MIME type: application/pdf
File uploaded to: https://generativelanguage.googleapis.com/v1beta/files/gasz4rkn0u3j application/pdf

API seems to be straight forward, and I used this docs:

Below is my API code:

const { GoogleAIFileManager } = require('@google/generative-ai/server');
const { GoogleGenerativeAI } = require("@google/generative-ai");
const express = require("express");
const axios = require("axios");
const fs = require("fs");
const path = require("path");
require("dotenv").config();
const tmp = require('tmp');
const mime = require('mime-types');

const app = express();
app.use(express.json());

// const API_KEY = process.env.GEMINI_API_KEY;
// const fileManager = new GoogleAIFileManager(API_KEY);
// const genAI = new GoogleGenerativeAI(API_KEY);


app.post("/process-pdf", async (req, res) => {
    const { pdfUrl } = req.body;
    
    if (!pdfUrl) {
        return res.status(400).json({ error: "PDF URL is required" });
    }

    try {
        // Step 1: Download PDF from URL and detect MIME type from response headers
        const response = await axios.get(pdfUrl, { responseType: 'arraybuffer' });
        const buffer = Buffer.from(response.data, 'binary');
        const mimeType = response.headers['content-type'];

        // Step 2: Create a temporary file for the downloaded PDF
        const tmpFile = tmp.fileSync({ postfix: `.${mime.extension(mimeType)}` });
        fs.writeFileSync(tmpFile.name, buffer);
        console.log(`Downloaded and saved PDF as: ${tmpFile.name}, MIME type: ${mimeType}`);

        const API_KEY = process.env.GEMINI_API_KEY;
        const fileManager = new GoogleAIFileManager(API_KEY);
        const genAI = new GoogleGenerativeAI(API_KEY);

        // Step 3: Upload the temporary PDF file to Gemini and get the file URI
        const uploadResult = await fileManager.uploadFile(tmpFile.name, {
            mimeType: mimeType,
            displayName: `Uploaded PDF from URL`,
        });
        const fileUri = uploadResult.file.uri;
        const updatedMimeType = uploadResult.file.mimeType;
        console.log(`File uploaded to: ${fileUri} ${updatedMimeType}`);

        
        const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });

        // Ensure the request structure aligns with the API requirements
        const result = await model.generateContent([
            {
              fileData: {
                mimeType: updatedMimeType,
                fileUri: fileUri,
              },
            },
            { text: "Can you summarize this document as a bulleted list?" },
          ]);
        
        tmpFile.removeCallback();

        return res.status(200).json({ "data":  result.response.text()});
    } catch (error) {
        console.error("Error processing PDF:", error);
        return res.status(500).json({ error: error.message });
    }
});

// Start server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
});

Any ideas please If I m doing something wrong?

Welcome to the forums!

I haven’t tested the code, but on the surface it looks correct.

I’m wondering if the issue is related to uploading the file. Some thoughts there:

  • Have you looked at uploadResult to see if any of the fields are out of the ordinary or if an error has been indicated?
  • I’ve personally had issues setting the displayName, although it is listed as a valid field, and others seem to be able to do it without issue.
  • Have you verified the uploadResult.file.state to make sure it is “AVAILABLE”?

What I’m wondering is if there is an issue with the upload, and this is causing an issue with the file when Gemini tries to use it.

1 Like

It seems that the doc was bigger than 50 mb and that s why it was not working.

According to the docs:

You can use the File API to upload a document of any size. Always use the File API when the total request size (including the files, text prompt, system instructions, etc.) is larger than 20 MB.

Note: The File API lets you store up to 20 GB of files per project, with a per-file maximum size of 2 GB. Files are stored for 48 hours. They can be accessed in that period with your API key, but cannot be downloaded from the API. The File API is available at no cost in all regions where the Gemini API is available.

Unless the File API refers to some other API than GoogleAIFileManager, I don’t understand the docs.

There was a comment somewhere on the forum by @Logan_Kilpatrick that the PDF limit is 300 pages, apparently regardless of file size.

Still an odd error.

My doc is 90 pages so I don’t think the issue. Is there a place to reach Google devs who support the Gemini API/Docs? Maybe there is a bug.

Posting here and sending feedback through AI Studio (three dots in upper right hand corner) are the best ways to send feedback.