Found while reproducing #5996. Filing so triage can rank it; not fixed there.
What I measured
b0de7a85c (PR #5995, card #5391) gave OBJECTSTACK_SPEC_DIST a fail-fast check: assertDependenciesResolve confirms the override's own manifest dependencies resolve from packageDir, and refuses the build otherwise. That check was written because an override whose deps cannot resolve does not fail at injection time — it fails much later, in ways that do not name the override.
OBJECTSTACK_CLIENT_DIST — its sibling hook in apps/console/vite.config.ts, ~70 lines above — got nothing equivalent. It is still a plain string alias:
constclientDistOverride=process.env.OBJECTSTACK_CLIENT_DIST;if(clientDistOverride){constresolved=path.resolve(clientDistOverride);workspaceAliases['@objectstack/client']=resolved;clientFsAllow.push(path.dirname(resolved),path.resolve(path.dirname(resolved),'..'));}No manifest is read, no dependency is checked, and the path is not verified to exist.
Reproduced on apps/console, vite@8.2.1 + rolldown@1.2.3, base 7c96c9420: copy the installed @objectstack/client@17.2.0dist/ to a directory outside the workspace and point the hook at it. Its three bare imports — @objectstack/core/logger, @objectstack/spec/api, @objectstack/spec/data — have no reachable node_modules from that location, so all three stay unresolved. vite build reports ✓ 8615 modules transformed and carries on; the three specifiers survive as external imports inside assets/framework-*.js, i.e. bare specifiers in a browser bundle that no browser can load.
The failure mode is exactly the one #5391 was filed about, on the other hook: nothing in the output names OBJECTSTACK_CLIENT_DIST, and the build's own summary reads as success up to the point something unrelated trips over the wreckage.
Why it is worth a line
The hook exists so a developer can exercise a locally built client before it ships — i.e. it is pointed at a freshly built, not-yet-installed tree, which is precisely the situation where node_modules is absent or incomplete. The validation #5995 wrote is directly transferable: assertDependenciesResolve and packageResolvesFrom in scripts/vite-objectstack-spec-dist.ts are already parameterised over a package directory.
Note the two hooks are not symmetrical in shape and a fix should not assume they are: the spec hook derives 18 aliases from the override's exports map, while the client hook is one alias and may legitimately point at either a package directory or a dist entry file. Only the dependency check transfers cleanly.
Possible shapes (not a recommendation)
- Extract the dependency-resolution check from
scripts/vite-objectstack-spec-dist.ts into something both hooks call, and have the client hook refuse the build the same way the spec hook now does. - Cheaper first cut: assert the resolved path exists and that the containing package's declared
dependencies resolve from it, without touching the spec module. - Consider whether unresolved bare imports in a browser bundle should fail the console build generally, independent of either hook — that is a wider question and probably its own card.
Related: #5391 / #5995 (the spec-dist half), #5996 (where this was found).
Found while reproducing #5996. Filing so triage can rank it; not fixed there.
What I measured
b0de7a85c(PR #5995, card #5391) gaveOBJECTSTACK_SPEC_DISTa fail-fast check:assertDependenciesResolveconfirms the override's own manifestdependenciesresolve frompackageDir, and refuses the build otherwise. That check was written because an override whose deps cannot resolve does not fail at injection time — it fails much later, in ways that do not name the override.OBJECTSTACK_CLIENT_DIST— its sibling hook inapps/console/vite.config.ts, ~70 lines above — got nothing equivalent. It is still a plain string alias:No manifest is read, no dependency is checked, and the path is not verified to exist.
Reproduced on
apps/console,vite@8.2.1+rolldown@1.2.3, base7c96c9420: copy the installed@objectstack/client@17.2.0dist/to a directory outside the workspace and point the hook at it. Its three bare imports —@objectstack/core/logger,@objectstack/spec/api,@objectstack/spec/data— have no reachablenode_modulesfrom that location, so all three stay unresolved.vite buildreports✓ 8615 modules transformedand carries on; the three specifiers survive as external imports insideassets/framework-*.js, i.e. bare specifiers in a browser bundle that no browser can load.The failure mode is exactly the one #5391 was filed about, on the other hook: nothing in the output names
OBJECTSTACK_CLIENT_DIST, and the build's own summary reads as success up to the point something unrelated trips over the wreckage.Why it is worth a line
The hook exists so a developer can exercise a locally built client before it ships — i.e. it is pointed at a freshly built, not-yet-installed tree, which is precisely the situation where
node_modulesis absent or incomplete. The validation #5995 wrote is directly transferable:assertDependenciesResolveandpackageResolvesFrominscripts/vite-objectstack-spec-dist.tsare already parameterised over a package directory.Note the two hooks are not symmetrical in shape and a fix should not assume they are: the spec hook derives 18 aliases from the override's
exportsmap, while the client hook is one alias and may legitimately point at either a package directory or adistentry file. Only the dependency check transfers cleanly.Possible shapes (not a recommendation)
scripts/vite-objectstack-spec-dist.tsinto something both hooks call, and have the client hook refuse the build the same way the spec hook now does.dependenciesresolve from it, without touching the spec module.Related: #5391 / #5995 (the spec-dist half), #5996 (where this was found).