pingdotgg / uploadthing

File uploads for modern web devs
https://uploadthing.com
MIT License
4.23k stars 315 forks source link

[bug]: build failure using vercel sensitive secrets on github action: Missing or invalid API key #787

Closed 4leite closed 5 months ago

4leite commented 6 months ago

Provide environment information

System:
    OS: Linux 6.1 Debian GNU/Linux 12 (bookworm) 12 (bookworm)
    CPU: (6) x64 Intel(R) Core(TM) i5-9600KF CPU @ 3.70GHz
    Memory: 19.77 GB / 31.28 GB
    Container: Yes
    Shell: 5.2.15 - /bin/bash
  Binaries:
    Node: 20.12.2 - ~/.local/share/pnpm/node
    Yarn: 1.22.22 - ~/.nvm/versions/node/v21.7.1/bin/yarn
    npm: 10.5.0 - ~/.local/share/pnpm/npm
    pnpm: 8.15.7 - ~/.local/share/pnpm/pnpm
  Browsers:
    Chrome: 124.0.6367.60
    Chromium: 124.0.6367.60
  npmPackages:
    typescript: ^5 => 5.4.5 
    uploadthing: ^6.10.1 => 6.10.1

Describe the bug

I have a project on vercel with Uploadthing secrets set to 'sensitive' I build the project on another machine:

vercel pull --environment=preview
vercel build

The build fails with the following error:

 ✓ Compiled successfully
 ✓ Linting and checking validity of types    
   Collecting page data  ..UploadThingError: Missing or invalid API key. API keys must start with `sk_`.
    at kc (/home/jon/gits/utapi-mre/.next/server/app/page.js:8:2854)
    at new kT (/home/jon/gits/utapi-mre/.next/server/app/page.js:8:15356)
    at 9914 (/home/jon/gits/utapi-mre/.next/server/app/page.js:8:16246)
    at t (/home/jon/gits/utapi-mre/.next/server/webpack-runtime.js:1:127)
    at 9908 (/home/jon/gits/utapi-mre/.next/server/app/page.js:1:16038)
    at t (/home/jon/gits/utapi-mre/.next/server/webpack-runtime.js:1:127)
    at 1502 (/home/jon/gits/utapi-mre/.next/server/app/page.js:1:1036)
    at t (/home/jon/gits/utapi-mre/.next/server/webpack-runtime.js:1:127)
    at n (/home/jon/gits/utapi-mre/.next/server/app/page.js:13:59490)
    at /home/jon/gits/utapi-mre/.next/server/app/page.js:13:59521

This is because the vercel sensitive secrets are not available on the build server at build time. The build should pass because the secret will be available at run time and the server action is not accessed at build time.

Link to reproduction

git@github.com:4leite/utapi-mre.git

To reproduce

git clone git@github.com:4leite/utapi-mre.git initialise a new project vercel

go to vercel dashboard and enter uploadthing credentials as sensitive secrets

image

vercel pull --environment=preview
vercel build

Additional information

The is only an issue with 'utapi' I'm using the buttons and other features from https://docs.uploadthing.com/getting-started/appdir without any problem even though the secrets are not available at build time.

I can work around this by adding a fake key in the utapi config: const utapi = new UTApi({ apiKey: process.env.UPLOADTHING_SECRET || "sk_" });

👨‍👧‍👦 Contributing

Code of Conduct

juliusmarminge commented 6 months ago

The build should pass because the secret will be available at run time and the server action is not accessed at build time.

well this doesn't seem to be what's happening, since you seem to be using utapi during render of a page so the prerendering fails.

CleanShot 2024-05-07 at 10 48 16@2x

4leite commented 6 months ago

Except it is what is happening. You can test it with the linked reproduction. If you're not convinced - this code produces the same error:

import { getImages } from "./uploadthing";

export default async function Home() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-between p-24">
      <button onClick={async () => {
        const images = await getImages();
        console.log(images);
      }} />
    </main>
  );
}

And the endpoint is only called on a user action in that case.

The problem is that the check for the env variable is made when the utapi instance is instantiated, rather than when any of it's methods are called.

const utapi = new UTApi() // <- check happens here
4leite commented 6 months ago

To be clear, if I move the instantiation into the server action, rather than at the top level of the file, that would also solve the problem. This is a minimal reproduction though and in my somewhat more complicated use-case I really want to be able to instantiate it inside a library that is then used in my code.

juliusmarminge commented 6 months ago

To be clear, if I move the instantiation into the server action, rather than at the top level of the file, that would also solve the problem. This is a minimal reproduction though and in my somewhat more complicated use-case I really want to be able to instantiate it inside a library that is then used in my code.

That's fair, but in the repo you sent you had it like this:

https://github.com/4leite/utapi-mre/blob/67c57d73b7bc3baca7c8f6e1d2ce45a15018a3f0/app/page.tsx#L8


To get back to the point though, I can successfully build our with-serveractions example without env vars, which seems to do the same thing as yours?

https://github.com/pingdotgg/uploadthing/blob/main/examples/with-serveractions/src/app/page.tsx

CleanShot 2024-05-07 at 15 46 42@2x

Yours do fail for me though, although I don't really see what's different 🤔

4leite commented 6 months ago

Yours has "use server" at the top level of the file, which causes subtly different behavior. My understanding is that will mean that the instantiation of the utapi is encapsulated within the created server action. It is equivalent to this:

export const getImages = async () => {
  "use server";
  const const utapi = new UTApi() // <- moving the instantiation here will build, but I want to avoid having to do that.

  const { files } = await utapi.listFiles();
  const { data } = await utapi.getFileUrls(files.map((file) => file.key));
  return data;
};
github-actions[bot] commented 6 months ago

This issue has been automatically marked as stale because it has not had any activity for 10 days. It will be closed in 5 days if no further activity occurs.

github-actions[bot] commented 5 months ago

This issue has been closed because it has not had any activity for 5 days since being marked as stale.