google / generative-ai-go

Go SDK for Google Generative AI
Apache License 2.0
592 stars 59 forks source link

googleapi: Error 500: Failed to convert server response to JSON when uploading the file using the example #208

Closed handsomefox closed 3 months ago

handsomefox commented 3 months ago

Description of the bug:

The following code from the examples at (https://ai.google.dev/gemini-api/docs/vision?lang=go#verify-file) fails with the error from the issue title (just replace a file with a real one).

package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "time"

    "github.com/google/generative-ai-go/genai"
    "google.golang.org/api/option"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("API_KEY")))
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    f, err := os.Open("GSFC_20180313_Jupiter_m12878_GreatRedSpot~orig.mp4")
    if err != nil {
        log.Fatal(err)
    }
    defer f.Close()

    opts := genai.UploadFileOptions{DisplayName: "Jupiter video"}
    response, err := client.UploadFile(ctx, "", f, &opts)
    if err != nil {
        log.Fatal(err)
    }

    var file *genai.File = response
    fmt.Printf("Uploaded file %s as: %q\n", file.DisplayName, file.URI)

    response, err = client.GetFile(ctx, file.Name)
    if err != nil {
        log.Fatal(err)
    }

    for response.State == genai.FileStateProcessing {
        time.Sleep(10 * time.Second)
        response, err = client.GetFile(ctx, file.Name)
        if err != nil {
            log.Fatal(err)
        }
    }

    fmt.Printf("File %s is ready for inference as: %q\n", response.DisplayName, response.URI)

}

This code also fails:

func uploadFileBytes(ctx context.Context, client *genai.Client, contentType string, data []byte) (*genai.File, error) {
    hash := sha1.Sum(data)
    name := hex.EncodeToString(hash[:])
    if len(name) > 40 {
        name = name[:40]
    }
    existing, err := client.GetFile(ctx, name)
    if err == nil {
        return existing, nil
    } else {
        slog.Error("[GEMINI] Failed to get existing file", "error", err)
    }

    opts := &genai.UploadFileOptions{MIMEType: contentType, DisplayName: name}
    file, err := client.UploadFile(ctx, name, bytes.NewReader(data), opts)
    if err != nil {
        slog.Error("[GEMINI] Failed to upload a file", "error", err)
        return nil, err
    }

    for file.State == genai.FileStateProcessing {
        slog.Info("Processing file", "filename", file.Name)
        time.Sleep(3 * time.Second)
        var err error
        file, err = client.GetFile(ctx, file.Name)
        if err != nil {
            slog.Error("[GEMINI] Failed to get a file", "error", err)
            return nil, err
        }
    }
    if file.State != genai.FileStateActive {
        return nil, fmt.Errorf("uploaded file has state %s, not active", file.State)
    }

    return file, nil
}

It logs:

"msg":"[GEMINI] Failed to get an existing file","error":"googleapi: Error 500: Failed to convert server response to JSON"}
"msg":"[GEMINI] Failed to upload a file","error":"googleapi: Error 409: eb085accc91f74fa38143c6cb0eb1c97ab2a1ac8 already exists., alreadyExists"}

Which means that the file exists, but client.GetFile has failed, somehow.

Actual vs expected behavior:

Actual:

The code fails on client.GetFile with error: googleapi: Error 500: Failed to convert server response to JSON

Expected:

client.GetFile works correctly and does not return an error.

Any other information you'd like to share?

Using: go 1.22.6, github.com/google/generative-ai-go v0.17.0

go env
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOOS='linux'
GOPATH='/home/suicedek/go'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/lib/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/lib/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.22.6'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build4110998487=/tmp/go-build -gno-record-gcc-switches'
eliben commented 3 months ago

This code works for me; can you try a different video file? For example, the .mp4 file from https://github.com/google/generative-ai-go/tree/main/genai/testdata

handsomefox commented 3 months ago

Hi! The problem is that this same code was working before as well, and now that I've checked - it works now as well.

This issue seems to be similar: https://github.com/google-gemini/generative-ai-js/issues/177

And the response from the author: "It just automagically fixed itself, don't know why. :) It works via Postman, gonna check if it works with AI SDK as well." applies here as well for me. idk

eliben commented 3 months ago

Thank you for the update; it sounds like a transient backend API problem. Going to close the issue for now