Skip to content

@object-ui/console publishes plugin.js from the package root, which turbo's build outputs do not cover — a cache hit restores an incomplete package #7855

Description

@claude

Found by the dev seat implementing #7276 while re-deriving that card's mechanism. Unassigned, unlabelled — recording a measurement, not claiming a priority.

The defect

turbo.json's build task declares:

"outputs": ["dist/**", ".next/**", "build/**", "**/*.tsbuildinfo", "!**/node_modules/**"]

@object-ui/console (apps/console, not private) publishes its entry from the PACKAGE ROOT, not from dist/:

"exports": { ".": { "types": "./plugin.d.ts", "import": "./plugin.js", "default": "./plugin.js" } },
"main": "./plugin.js",
"files": ["dist", "plugin.ts", "plugin.js", "plugin.d.ts", "README.md"]

plugin.js and plugin.d.ts are produced by build:plugin (tsc -p tsconfig.plugin.json), are gitignored (apps/console/.gitignore:16), and match none of the outputs globs. So they are neither hashed as inputs nor stored as outputs: a cache hit for @object-ui/console:build restores dist/ and leaves the package's published entry absent.

Measured

On origin/main 52cac38, two worktrees of the same commit, turbo 2.10.9:

  1. Worktree A ran a cold pnpm build — 43 tasks, 3m46.7s. apps/console/plugin.js present.
  2. Worktree B ran pnpm build — 43 of 43 cache hits, 272ms, FULL TURBO.
  3. In worktree B: apps/console/dist/ fully restored, apps/console/plugin.js does not exist.

pnpm check:node-esm-load in worktree B then reported exactly the line #7276 quoted from a real run:

✗ @object-ui/console: no-build-output — ./plugin.js does not exist after the build

Why this is worth a card

This is the mechanism behind the loud half of #7276, and it outlives that card's fix. #7276 makes the ESM-load gate refuse to grade artifacts another tree produced — that turns the misattributed red into an accurate one, but it does not make the cache entry complete. Anything else that consumes a cached @object-ui/console build still gets a package whose declared entry is missing, and the tell is a no-build-output style failure pointing at a package the author did not touch.

The narrow fix is to declare the two files as outputs — either widening the shared build task in turbo.json, or (smaller blast radius) giving apps/console a package-level turbo.build.outputs that adds plugin.js and plugin.d.ts. Whether any OTHER package publishes from its root should be checked in the same pass rather than assumed: the audit is exports/main targets that do not start with ./dist/.

Not fixed in #7276's PR: that card's declared file surface is the gate script and its test, and turbo.json was explicitly limited there to "only if the fix requires it". It did not.

Refs: #7276 (where this surfaced) · #1760 (the adjacent cache-masking case)


Generated by Claude Code

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

    Labels

    bugSomething isn't workingdomain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repofindingpm:queuepriority:p2tooling

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions