openai-node icon indicating copy to clipboard operation
openai-node copied to clipboard

400 'file' is a required property when Creating File in CloudFlare Worker

Open EvanPiro opened this issue 9 months ago • 5 comments

Confirm this is a Node library issue and not an underlying OpenAI API issue

  • [X] This is an issue with the Node library

Describe the bug

I get the following error when I try to create a file from a CloudFlare worker environment.

 {
      error: {
        message: "'file' is a required property",
        type: 'invalid_request_error',
        param: null,
        code: null
      }
    }

I'm able to successfully create a file from a vanilla nodejs environment. I've also confirmed that CURL requests are working.

To Reproduce

Run the following code in a CloudFlare worker environment.

 const llm = new OpenAI({
    apiKey: env.OPENAI_API_KEY,
  });

  
  const file = await toFile(
    new FormDataBlob([
      new TextEncoder().encode("text is here"),
    ]),
    "finetune.jsonl"
  );

  const res = await llm.files.create({
    file,
    purpose: "fine-tune",
  });

Code snippets

No response

OS

macOS

Node version

v18.0.0

Library version

4.38.5

EvanPiro avatar Apr 29 '24 20:04 EvanPiro

Has anyone else experienced this? This is a product level blocker on my end and I'm willing to assist in the fix.

EvanPiro avatar May 07 '24 17:05 EvanPiro

Thanks for reporting, we'll take a look soon. In the meantime, you might try methods other than FormDataBlob to instantiate the file contents, like converting the string to an ArrayBuffer.

rattrayalex avatar May 13 '24 00:05 rattrayalex

I came up against this as well. I was trying to upload a PDF, but couldn't get the lib to accept anything other than a FsFileStream from fs.createReadStream. Not blobs, buffers, formdata Files, nothing. It'd either error with the OP's 'file' is required property, or reject the type in addFormValue.

It'd be nice if it could accept a regular Readable stream, not just a file stream from fs. Or maybe a custom openai File object that specified the buffer/stream plus filename and other file metadata that a plain stream / buffer doesn't specify.

After looking at the code, my workaround was to make something that would pass through isFileLike(). This works:

const file = {
  type: 'application/pdf',
  name: 'test.pdf',
  filename: 'test.pdf',
  lastModified: new Date().getTime(),
  arrayBuffer: () => convertThingYouHaveToBuffer(),

  // It doesn't use these, but it needs them to work around type checking
  size: 1,
  text: () => '',
  slice: () => [],
}

benogle avatar May 18 '24 04:05 benogle

@benogle I've tried that and am still getting the same error. Here is my code:

    const id = uuidv4();

    await env.DOC_BUCKET.put(id, trainingStr);

    const obj = await env.DOC_BUCKET.get(id);

    const file = {
      type: "application/jsonl",
      name: "training.jsonl",
      filename: "training.jsonl",
      lastModified: new Date().getTime(),
      arrayBuffer: async () => await obj.arrayBuffer(),

      // It doesn't use these, but it needs them to work around type checking
      size: 1,
      text: async () => await obj.text(),
      slice: (): any => [],
    };

    const res = await llm.files.create({
      file,
      purpose: "fine-tune",
    });

EvanPiro avatar May 27 '24 20:05 EvanPiro

Sorry we haven't been able to take a look at this yet. We've been backed up with other things but do hope to get to it in the next month or so.

rattrayalex avatar Jul 07 '24 21:07 rattrayalex