Skip to content

fix(install): check the schema instead of migrating in the function - #244

Merged
jouwdan merged 1 commit into
mainfrom
claude/mei-133-installer-checks-schema
Aug 26, 2026
Merged

fix(install): check the schema instead of migrating in the function#244
jouwdan merged 1 commit into
mainfrom
claude/mei-133-installer-checks-schema

Conversation

@jouwdan

@jouwdan jouwdan commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Third bug from the same deploy, after #240 and #243. The board now renders its own text and its own styling; /install step 1 fails:

"Apply migrations" did not finish. Cannot find the migrations. Set MIGRATIONS_DIR to the folder holding meta/_journal.json — looked in /var/task/node_modules/@meith/db/migrations, …

Cause

@meith/db ships migrations in its files allowlist, and the package's JS is plainly in the function — the code ran far enough to raise this. The .sql files and meta/_journal.json are not, because they are data nothing imports.

Nothing can put them there either. next build defaults to Turbopack in Next 16, and Next skips trace collection entirely for it — next/dist/build/index.js:1627:

if (bundler !== _bundler.Bundler.Turbopack && !isGenerateMode && !buildTracesPromise) {
    buildTracesPromise = collectBuildTraces(...)
}

So outputFileTracingIncludes never runs. That also makes the @swc/helpers entry from MEI-120 inert — a second guard believed to be protecting the build that does not execute. Filed on MEI-133 for a separate look; not touched here.

Why the step had nothing to do anyway

vercel.json's build command is community migrate && forum-web build --at-root, which migrates in the build container where the files do exist. The schema was current before the app ever served a request.

The fix

The step confirms every table is there and stops with the names of any that are not. The names come from the schema definitions — ordinary imported code, present wherever the board runs at all — so nothing reads a file. 72 tables are discoverable that way.

A serverless function was the wrong place for this regardless of the missing files: several cold starts contend for one migration lock, and the function timeout bounds how long a migration is allowed to take. The board migrates where it deploys — community migrate in the build command, docker-entrypoint.sh before a container serves anything — so self-hosted behaviour is unchanged.

Two things found on the way

  • The failure copy was being built in @meith/db, which has no business holding user-facing prose and no translator to hold it with. It moved to the catalog.
  • install.raced.sealed and install.raced.inFlight were already thrown as catalog keys and rendered raw — an operator hitting either saw the literal string install.raced.sealed. Rendering the step error through fromCopy fixes that too; it falls back to the raw string, so every other thrown message is unchanged.

Verification

  • pnpm verify green — 7,876 tests, 449 files
  • the schema check is exercised with tables renamed away, which is the path CI could not reach before: its boards install a full node_modules, so the migration files were always present
  • a test holds the form's copy to the keys the server throws, so a key added without copy behind it fails rather than shipping as raw text — confirmed by removing the new key and watching it fail
  • no code comments; the reasoning is in docs/vercel.md and docs/quickstart.md, per AGENTS.md

Fixes MEI-133.


Generated by Claude Code

The installer's first step applied migrations, which needs the `.sql`
files beside `@meith/db`. On Vercel they are not in the function: nothing
imports them, so nothing traces them in, and `outputFileTracingIncludes`
cannot put them back because `next build` defaults to Turbopack and Next
skips trace collection entirely for it. The board's own build command
already migrates before it builds, so the schema was current and the
installer was failing on a step with nothing left to do.

It now confirms every table is there and stops with what is missing. The
names come from the schema definitions — ordinary imported code, present
wherever the board runs — so nothing reads a file. A serverless function
was the wrong place for this regardless: several cold starts contend for
one migration lock, and the function timeout bounds how long a migration
may take.

The failure copy goes through the catalog rather than being built in
`@meith/db`, which has no business holding user-facing prose. Rendering it
through `fromCopy` also fixes `install.raced.sealed` and
`install.raced.inFlight`, which were already thrown as catalog keys and
until now reached the operator as the literal key text.

Docs move with it: the step is named in `docs/quickstart.md`, which every
other route points at, and `docs/vercel.md` gains why the files cannot be
in the function and why `MIGRATIONS_DIR` will not help there.

A test holds the form's copy to the keys the server throws, so a key added
without copy behind it fails rather than shipping as raw text. The schema
check is exercised with tables renamed away, which is the path CI could
never reach before: its boards install a full node_modules, so the
migration files were always present.
@jouwdan
jouwdan merged commit 156b625 into main Aug 26, 2026
13 of 14 checks passed
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