Skip to content

node CLI bundles ship asset URLs instead of text content (prompts, tool descriptions) #41853

Description

@kitlangton

What

The vite-built node CLI (build-node.ts, published by publish.yml build-node-cli for 5 targets) ships .txt imports as asset URL strings instead of their content. Verified on current v2 by inspecting dist-node/opencode.mjs:

PROMPT_ANTHROPIC = "/assets/anthropic-Df_a6ajX.txt"   // ← the Anthropic system prompt is this literal string
// likewise the default session prompt (session/runner/prompt/base.txt via model-request.ts)
// and the patch tool description (tool/plugin/patch.ts)

SSR builds do not even emit the asset files, so the URLs point at nothing — published node CLIs are running with URL paths where prompt text should be.

Why

.txt is in Vite's built-in KNOWN_ASSET_TYPES, so its core asset plugin claims those modules before the normal-priority rawTextPlugin load hook runs. .md imports work only because .md is not a known asset type.

Why nobody noticed

The bundle builds cleanly and --version/--help run fine — nothing evaluates the imported strings on that path, and at runtime a wrong prompt degrades quality rather than crashing. The bun-compiled CLI (the primary artifact) inlines text correctly, masking the node artifact.

Fix

One line: enforce: "pre" on rawTextPlugin in packages/cli/vite.node.config.ts, plus a build assertion that fails when any text import surfaces as an asset URL (only content assertions catch this class). Both are already implemented and verified in #41838 (they ride with the models.dev snapshot change, which made the same bug loud). If #41838 stalls, the two changes extract cleanly into a standalone fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions