Fix the production playground: embed the bundled assets - #8
Merged
Merged
Conversation
The hosted playground failed in production on every spec with "bundled asset missing: journey.webmcp.ts". The tools output always writes the journey helper and the agent skill, and assetText() read them from the package's assets/ directory with fs at runtime. That read is invisible twice over: - webpack bundles the package into the route and rewrites import.meta.url to the build machine's absolute path, so it succeeded locally from a developer's own checkout - Next's file tracer cannot see a readFile whose path is computed, so assets/ never entered the function bundle (the traced-files manifest listed the package's package.json and nothing else) The assets are now embedded at package build time: assets.ts imports them as text (?raw), which vitest resolves natively and tsup resolves with a small esbuild plugin. The shipped code carries the text, so no host has to be told about these files. assets/ stays the reviewed source of truth and a test asserts the embed matches it byte for byte. A trace include in the site config would have fixed this one host and left every other serverless use of the pipeline to rediscover the trap. Static new URL references were tried first and rejected: webpack rewrites them into web-served asset URLs that readFile cannot open. Verified against the deployment condition: with packages/codegen/assets deleted, next build plus next start generated 19 tools from the Petstore spec and 6 from the Immich excerpt, both 200. Before, the same test returned 422 with the error above. A real generate run still writes the journey helper and the skill byte-identical to assets/.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
Every production playground request failed:
Generating tools always writes the journey helper and the agent skill, and
assetText()read both from the package'sassets/directory withfsat runtime. Two things hid that until deploy:import.meta.urlto the build machine's absolute path. On a laptop that path exists, so the read succeeded from the developer's own checkout. On Vercel the same literal became/vercel/path0/....readFilewhose path is computed, soassets/never entered the function bundle. The traced-files manifest for the route (.next/server/app/api/playground/route.js.nft.json) listed the package'spackage.jsonand nothing else.So the failure was environment-shaped: fine locally, broken in every deployment.
The fix
The assets are embedded at package build time.
assets.tsimports them as text (?raw), which vitest resolves natively and tsup resolves with a small esbuild plugin in the newpackages/codegen/tsup.config.ts. The shipped code carries the text, so it never reads its own files at runtime and no host needs tracing configuration for them.assets/stays the reviewed source of truth, and a new test asserts the embed matches it byte for byte.Alternatives tried and rejected
outputFileTracingIncludesinsite/next.config.mjs. Works, but it fixes this one host and leaves every other serverless use of the pipeline to rediscover the trap. The package now invites exactly that use by shippingrunGenerateanddashboardState.new URL("../assets/...", import.meta.url)references so tracers notice the files. Webpack rewrites those into web-served asset URLs (/_next/static/media/SKILL.<hash>.md), andreadFilecannot open a web path. I caught this by deletingassets/and running the production server, which still failed. That test is the reason the fix is embedding rather than tracing.Verification
The deployment condition, reproduced locally: delete
packages/codegen/assets,next build,next start, then POST specs.Also checked:
createJourneypresent) with zerostatic/mediaasset references and no bakedfile:///build paths.runGenerateinto a scratch dir still writesjourney.webmcp.tsand.agents/skills/webmcp-tools/SKILL.mdbyte-identical toassets/.pnpm lint,pnpm typecheck,pnpm test,pnpm buildall pass. Package tests 242, site tests 11.After merge
Vercel redeploys
mainautomatically, so the production playground should work without further changes. The changeset is apatchfor@webmcp-stack/codegen, worth consuming in a release because the npm package had the same defect; the site itself needs no release, since it consumes the workspace package.