cli icon indicating copy to clipboard operation
cli copied to clipboard

Cannot run edge function due to outdated deno runtime

Open point-source opened this issue 1 year ago • 15 comments

Bug report

Describe the bug

I wrote a supabase edge function a few weeks ago and successfully deployed it. Yesterday I went to edit it and realized I could not run it locally as I used to.

It appears that as deno continues to update their std library, functions will automatically use newer and newer versions of this library. In this case, my function's dependencies are now using std 0.153.0 which is incompatible with deno 1.20.3 (which is what supabase uses).

In order to get my application to work, I either need to find a way to force the std library down to 0.152.0 or get supabase to run something newer than 1.20.0. Since I don't import std myself but rather my dependencies do, I don't see a way to control which version of std I get.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Create a new supabase function: supabase functions new hello
  2. Edit the function and add a dependency such as import "https://esm.sh/[email protected]";
  3. Run the function with supabase supabase functions serve hello --debug and observe the error output
  4. Run the function with deno cli 1.20.3 and observe the same error: deno run supabase/functions/hello/index.ts
  5. Run the function with deno cli 1.26.0 and observe that it works because 1.26.0 is compatible with std 0.153.0 while deno 1.20.3 is not

In case it helps, in my testing I used asdf as a version manager to be able to switch between deno versions.

Expected behavior

I expect there to be a way to force either the deno version or library version or both when running locally as well as remote. Otherwise, a deterministic runtime environment is not possible and this reduces the viability of the edge functions feature.

System information

  • OS: macOS 12.6 (M1)
  • Version of supabase-js: 1.35.6
  • Version of Deno: 1.20.3 and 1.26.0
  • Version of supabase-cli: 1.5.0

point-source avatar Sep 29 '22 23:09 point-source

Thanks for reporting this @point-source, we pinned the Deno version a while ago because of an issue with deno bundle. But since this is starting to be a blocker for some, we'll see if the latest version resolves this issue.

soedirgo avatar Sep 30 '22 04:09 soedirgo

Of course! That said, many other cloud function providers allow the dev to either specify the runtime version or provide a list of acceptable versions. I feel like this would probably be important to ensure that deployed functions do not suddenly break if the supabase backend is updated. Or is a deployed function always run with the same deno version it was deployed with?

point-source avatar Sep 30 '22 04:09 point-source

It's always run with the latest stable Deno version - this is the behavior of Deno Deploy, which we use under the hood.

soedirgo avatar Sep 30 '22 05:09 soedirgo

Hello @soedirgo

This version of deno works with Stripe in local dev? because when I try to import Stripe import Stripe from "https://esm.sh/stripe?target=deno&no-check";

and serve It's fail

logs:

error: TS2345 [ERROR]: Argument of type '"CAA"' is not assignable to parameter of type 'RecordType'.
        this.#query(name, "CAA").then(({ ret }) => {
                          ~~~~~
    at https://deno.land/[email protected]/node/internal_binding/cares_wrap.ts:266:27

TS2694 [ERROR]: Namespace 'Deno' has no exported member 'CAARecord'.
          (ret as Deno.CAARecord[]).forEach(({ critical, tag, value }) =>
                       ~~~~~~~~~
    at https://deno.land/[email protected]/node/internal_binding/cares_wrap.ts:267:24

TS2322 [ERROR]: Type '"CAA"' is not assignable to type 'RecordType'.
              type: "CAA",


... etc

WithMyTeam avatar Oct 06 '22 04:10 WithMyTeam

You might need to use an earlier version of stripe - the latest version might be using a std version that's incompatible with the pinned Deno version used by the CLI.

soedirgo avatar Oct 06 '22 06:10 soedirgo

It seems to me that if deno deploy always runs the latest stable version, then so should supabase. Even if this breaks deno bundle/stripe, it would also be broken on pure deno deploy as well. In that case, it should be reported and handled by deno, not by supabase since supabase is a proxy to deno and has no responsibility for stripe. Am I misunderstanding the situation?

point-source avatar Oct 06 '22 11:10 point-source

I think it should have the possibility to choose his version of the deno runtime on supabase in a config file, is this envisaged?

WithMyTeam avatar Oct 07 '22 04:10 WithMyTeam

I done tests just with deno without supabase.

effectively with the deno runtime version 1.21.1, it's fails

but with the last version 1.26.0 it's works

it's possible to upgrade the version of deno to 1.26.0? or/and to add the possibility to add the runtime version of deno?

WithMyTeam avatar Oct 07 '22 04:10 WithMyTeam

We don't plan to support setting the Deno version as that adds a point of failure. Maybe the solution right now is to use the latest Deno version and disable checks - I'll check this with the team.

Edit: actually that wouldn't solve things - as per the deno bundle issue linked above, the bundling will run successfully, but it will fail to run. You can test this like:

deno --version # deno 1.26.0
deno bundle --no-check=remote --quite supabase/functions/your-function/index.ts > out.ts
deno run out.ts

As for why it works on Deno Deploy, they use a different serialization format which I'm guessing doesn't have this problem (I'm not too savvy on the technical details). We're moving to using this too on our platform - will update here once it's available.

soedirgo avatar Oct 07 '22 05:10 soedirgo

Is the a workaround I can employ today to get my app working again until the team can review this?

point-source avatar Oct 09 '22 22:10 point-source

Can you try this?

import { serve } from "https://deno.land/[email protected]/http/server.ts";
// Deno CLI v1.20.3 is compatible with Deno std 0.132.0: https://raw.githubusercontent.com/denoland/dotland/main/versions.json
// append `&deno-std=0.132.0` on all esm.sh imports
import Plaid from "https://esm.sh/[email protected]?target=deno&deno-std=0.132.0";
import Stripe from "https://esm.sh/[email protected]?target=deno&deno-std=0.132.0";

console.log(Plaid, Stripe);

serve(async (req) => {
  try {
    return new Response();
  } catch (error) {
    return new Response(JSON.stringify({ error: error.message }), {
      status: 400,
    });
  }
});

soedirgo avatar Oct 10 '22 05:10 soedirgo

Hello @soedirgo

When I try with &deno-std=0.132.0 for each libraries I import, it's works for me.

This is good progress 👍

WithMyTeam avatar Oct 11 '22 05:10 WithMyTeam

@soedirgo your suggestion worked for my plaid lib import from esm.sh but did not work for my deno.land import of Opine 2.3.3. This is expected behavior and would normally mean that Opine needs an update but that project has been moved to maintenance mode in favor of using express via deno 1.25's npm compatibility mode. (I have my own separate opinions about their decision to do so before npm compat is stable but that's outside the scope of this ticket)

So now I have plaid working but Opine failing with the same error. My options are either ditch opine and lose an express-like syntax for my code wait until Supabase updates to at least deno runtime 1.25 so I can use express itself. Any other workaround ideas?

Just restating for posterity, it really seems like Supabase should just always match the current deno runtime version so that it behaves exactly the same as deno deploy. That way, all issues are deno issues instead of Supabase issues.

point-source avatar Oct 12 '22 13:10 point-source

I was able to import Opine with import Opine from "https://deno.land/x/[email protected]/mod.ts" - that seems like the closest version that works.

soedirgo avatar Oct 12 '22 15:10 soedirgo

Good call! That does appear to work as far as running it. Now I'm hitting a function size limit when I try to deploy it to supabase. That's out of scope for this ticket though.

point-source avatar Oct 12 '22 15:10 point-source

Good news - we've removed the Deno version pin in https://github.com/supabase/cli/pull/601! Can you check if your function can be deployed now? (You might need to update the CLI)

Here's the snippet I used to test this:

import { serve } from "https://deno.land/[email protected]/http/server.ts";
import Plaid from "https://esm.sh/[email protected]?target=deno&no-check";
import Stripe from "https://esm.sh/[email protected]?target=deno&no-check";
import Opine from "https://deno.land/x/[email protected]/mod.ts";

console.log(Plaid, Stripe, Opine);

serve(async (req) => {
  try {
    return new Response();
  } catch (error) {
    return new Response(JSON.stringify({ error: error.message }), {
      status: 400,
    });
  }
});

soedirgo avatar Nov 17 '22 07:11 soedirgo

Sure enough, that fixed it! Thanks @soedirgo :D

point-source avatar Nov 28 '22 19:11 point-source