Skip to content

workspace: include globs match directories without package.json, and the resulting "Cannot find entry" error names the root config instead of the offending directory #1067

Description

@relanse

Reproduction link or steps

Repro repo: https://github.com/relanse/tsdown-ghost-dir-repro

git clone https://github.com/relanse/tsdown-ghost-dir-repro
cd tsdown-ghost-dir-repro
npx tsdown@latest

Layout:

  • tsdown.config.ts — workspace: ['pkgs/*'] with a root-level entry: ['src/{index,ghost}.ts']
  • pkgs/real/ — a real package whose src/index.ts matches the entry glob
  • pkgs/ghost/ — a directory with no package.json and no tsdown config (only a .gitkeep; e.g. a stale leftover after a package rename)

What is expected?

Either:

  • Directories that contain neither a package.json nor a tsdown config file are skipped, and pkgs/real builds successfully; or
  • The error names the offending directory (pkgs/ghost) instead of the root config.

What is actually happening?

The whole build fails with an error labeled with the root config's name, and the message contains no path:

ERROR  Error: [repro-root] Cannot find entry: ["src/{index,ghost}.ts"]

pkgs/real/src/index.ts exists and matches the entry glob, but the build never reaches it: the package-less pkgs/ghost also gets built — it has no config of its own, so it inherits the root entry via mergeConfig(normalized, config) — and entry resolution matches nothing inside that directory.

In src/config/workspace.ts, include: 'auto' globs **/package.json so it only ever finds real packages, but a user-provided include array globs directories (onlyDirectories: true) with no package-ness check. The error's nameLabel (src/features/entry.ts) then carries the merged config's inherited root name.

Any additional comments?

Verified with tsdown 0.23.0 and 0.22.2, Node v24.16.0, Windows 10.

We hit this in the deepseek-harness monorepo (~270 packages), whose root tsdown config drives workspace builds this way (workspace: ['vendor/*', 'packages/*/*', 'apps/cli']). One stale directory left behind after a package rename — Windows file locks commonly prevent git from fully removing directories — broke pnpm run build for the whole monorepo with an error pointing at the root package. Locating the actual culprit took a long time precisely because the message carries no path.

Suggested fix (either or both):

  1. After globbing user-provided include patterns, drop directories containing neither package.json nor a tsdown config file (maybe log at debug level).
  2. Include the resolved cwd in the Cannot find entry error so the offending directory is identifiable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggood first issueGood for newcomers

    Type

    Fields

    Priority

    None yet

    Effort

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions