Skip to content

fix: resolve npm: supabase-js specifier for offline edge-runtime image - #517

Merged
Ziinc merged 3 commits into
mainfrom
claude/fix-failing-ci-vnb95f
Sep 24, 2026
Merged

Ziinc merged 3 commits into
mainfrom
claude/fix-failing-ci-vnb95f

Conversation

@Ziinc

@Ziinc Ziinc commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • CI (Supabase Docker workflow, single-tenant self-hosted image job) was failing: exchange-desktop-token and github-webhook edge functions returned 500 for every request instead of proper 400/401 validation responses.
  • Root cause: feat: implementation of sprites, update to use npm: #513 switched edge function imports to npm:@supabase/supabase-js@2.95.3, but the offline fat image only remapped the old esm.sh specifier to a vendored bundle. The npm: specifier fell through to a live registry fetch, which the offline edge-runtime container can't do, so every function invocation threw.
  • Rather than just patching the import-map remap, replaced the esbuild+Node vendor-bundle approach entirely: a build stage now pre-warms Deno's own npm cache (DENO_DIR) for the pinned @supabase/supabase-js version via deno cache, and that cache is shipped directly in the image. No node_modules, no bundling step, no import-map remapping — functions resolve their npm: import from disk like they would with a normal Deno cache.

Changes

  • supabase/docker/Dockerfile: removed the Node+esbuild vendor stage; added an npm-cache stage (denoland/deno:alpine-2.1.4) that runs deno cache and copies the resulting DENO_DIR into the final image.
  • supabase/docker/deno.json: dropped the import-map remapping; now only pins "nodeModulesDir": "none" so the shipped image never falls back to a local node_modules directory.
  • supabase/docker/openrc/run-edge-runtime.sh, README.md, versions.env: updated comments/docs to match.

Test plan

  • Verified the new npm-cache build stage in isolation (docker build --target npm-cache): correctly resolves and caches @supabase/supabase-js@2.95.3 and its full dependency tree.
  • Full docker build of the fat image could not be completed in the dev sandbox (unrelated pre-existing Alpine/apk TLS limitation in that sandbox, reproduced against a bare alpine:3.23 image too) — needs confirmation from the real CI run, which doesn't have that constraint.
  • supabase/docker/test/verify-self-hosted.sh (exchange-desktop-token / github-webhook checks) should be re-verified green in CI.
    🤖 Generated with Claude Code
    https://claude.ai/code/session_01T81HxmDYzHnYp5kg24ByLX
    Generated by Claude Code

PR #513 switched edge functions from the esm.sh specifier to
npm:@supabase/supabase-js@2.95.3, but docker/deno.json only remapped
the esm.sh URL and the bare specifier. The npm: specifier fell through
to a live registry fetch, which the offline edge-runtime container
can't do, so every edge function request failed with a 500
(exchange-desktop-token and github-webhook CI checks failing).
Edge functions already import @supabase/supabase-js via its npm:
specifier. Instead of bundling it into a single ESM file with Node +
esbuild and remapping imports through deno.json, pre-warm Deno's own
npm cache (DENO_DIR) for the pinned version in a `deno cache` build
stage and ship that cache directly. No node_modules, no bundling step,
no import-map remapping.

deno.json now only pins nodeModulesDir to "none" so the shipped image
never falls back to a local node_modules directory.

@Ziinc Ziinc left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline notes on the two files with non-obvious rationale.


Generated by Claude Code

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced the vendor stage (Node + esbuild bundling @supabase/supabase-js into a single .mjs) with an npm-cache stage that runs deno cache against the pinned npm:@supabase/supabase-js@2.95.3 specifier.

  • The functions already import via npm:... (feat: implementation of sprites, update to use npm: #513); the vendor bundle's import-map remap only covered the old esm.sh URL, so every function call was hitting a live registry fetch at runtime and failing with 500 — this is the actual CI fix.
  • DENO_DIR is a stable Deno cache format, so warming it with the plain deno CLI and copying it into the image (same DENO_DIR path edge-runtime already uses) is compatible without needing edge-runtime itself at build time.
  • No node_modules, no esbuild, one fewer toolchain in the build.

Generated by Claude Code

Comment thread supabase/docker/deno.json

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dropped the imports remap entirely — no code imports the bare @supabase/supabase-js or esm.sh specifiers anymore, so there was nothing left to remap.

  • "nodeModulesDir": "none" is the important part: this file is copied over functions/deno.json (which sets nodeModulesDir: "auto" for local dev), so without this override the image would fall back to creating a local node_modules — exactly what pre-warming DENO_DIR is meant to avoid.

Generated by Claude Code

Remove the deno-cache build stage; @supabase/supabase-js now resolves
purely via its npm: specifier when edge-runtime loads a function,
same as any other npm: import. No pre-warming, no vendoring.
@Ziinc
Ziinc merged commit 75ec617 into main Sep 24, 2026
16 checks passed
@Ziinc
Ziinc deleted the claude/fix-failing-ci-vnb95f branch September 24, 2026 01:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants