Skip to content

[finding] @objectstack/service-cluster's dist/*.d.ts vanished AFTER its own build reported 3/3 declared declaration file(s) present — a downstream typecheck then failed TS7016 against a package that had built green #15042

Description

@hotlong

Observed while building the workspace closure for the option-B acceptance pin (#15004, PR #15039). Filed unassigned and label finding: the consequence class is severe and the observation is exact, but the CAUSE is not established and I could not reproduce it on demand. Triage owns the severity.

What was measured

pnpm --workspace-concurrency=2 --filter '@objectstack/cli^...' build on origin/main 33681eaef, in a fresh worktree with a fresh pnpm install. The build ran the package's own script — rm -rf dist && tsup && node ../../../scripts/check-dts-emitted.mjs — and its last three lines for this package were:

packages/services/service-cluster build: DTS dist/index.d.cts 35.03 KB
packages/services/service-cluster build: DTS dist/index.d.ts   35.03 KB
packages/services/service-cluster build: DTS dist/testing.d.ts 794.00 B
packages/services/service-cluster build: check-dts-emitted: @objectstack/service-cluster - 3/3 declared declaration file(s) present.
packages/services/service-cluster build: Done

The whole closure exited 0.

Some time later in the same session — after a repo-wide pnpm lint, several check:* gate runs and two vitest run invocations, with no further build and no rmls packages/services/service-cluster/dist/ held:

index.cjs  index.cjs.map  index.js  index.js.map  testing.js  testing.js.map

Every .d.ts / .d.cts gone. dist/testing.cjs gone too. The .js / .cjs outputs and their maps survived.

Why that is worse than a build failure

@objectstack/service-cluster is a dependencies entry of @objectstack/runtime, and packages/runtime/src/runtime.ts imports it. Any tsc program that reaches runtime's source then reports:

../runtime/src/runtime.ts(9,8): error TS7016: Could not find a declaration file for module '@objectstack/service-cluster'.
  '/…/packages/services/service-cluster/dist/index.js' implicitly has an 'any' type.

That is the LOUD half. The quiet half is the one this repo already has scar tissue about (#7668, #12078, scripts/check-test-source-alias.mjs's header): a package whose declarations are ABSENT makes an importing symbol any, and a suite that reads that symbol can run green against a type it is no longer checking, with nothing in the output saying so. Here it was loud only because noImplicitAny caught the direct import; a consumer reaching it through a re-export would not have been.

Recovered with pnpm --filter @objectstack/service-cluster build, after which the same typecheck reported the expected pre-existing numbers exactly.

What is NOT established, stated so nobody re-derives it as fact

Why it is worth a card even unreproduced

The failure mode is "a package's declarations are absent from a tree that built green". Every downstream type verdict taken in that window is a verdict about a .d.ts that is not there — and the direction that does NOT throw is a suite passing against any. If this is a real race rather than a one-off, it makes any local typecheck reading in this repo conditional on something nobody currently observes.

A cheap first step, if triage wants one: have check-dts-emitted (or a sibling) re-run over the whole closure once at the END of a --filter '<pkg>^...' build, rather than only per-package immediately after that package's tsup. That would convert a silent window into a named failure without needing the cause first.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions