Skip to content

chore(infra): an undeclared dependency resolves through pnpm's hoisted fallback — nothing catches a phantom dep #581

Description

@EricAndrechek

Area: infra · chore — gap · found via the #579 astro bump (pm-triage status sweep)

Expected: a workspace package that imports a module it does not declare in its own package.json fails to resolve — that is the point of pnpm's isolated node_modules.
Actual: it resolves anyway. Nothing in this repo restricts pnpm's hoisting: there is no .npmrc in the tree, and pnpm-workspace.yaml sets no hoist, hoist-pattern, public-hoist-pattern or nodeLinker. pnpm's defaults (hoist: true, hoist-pattern: ['*']) therefore place every transitive package into the virtual store's node_modules/.pnpm/node_modules, which Node reaches as a resolution fallback. make verify has no check for it either — verify-parallel (Makefile:557) runs lint-ts, typecheck-ts and check-docs, none of which compare imports against declared dependencies, and there is no depcheck/knip anywhere in Makefile, scripts/ or .github/.

Impact: a phantom dependency installs green, builds green and ships — until the transitive copy it was borrowing moves or disappears, at which point it breaks with no repo change to point at. This already happened and was caught by hand, not by tooling: the docs site relied on an undeclared @astrojs/markdown-remark, reachable only through the hoisted fallback. docs/astro.config.mjs sets markdown.remarkPlugins/rehypePlugins, astro's coerceLegacyMarkdownPlugins() does await import("@astrojs/markdown-remark") and throws when it cannot resolve — so a narrower hoist pattern, or a @astrojs/mdx/starlight bump dropping that dependency, would have taken the docs build down. #579 declared it explicitly (docs/package.json:16), fixing that one instance; the class is unguarded.

Note: the cheap end is a declared-vs-imported check in verify; the thorough end is turning the fallback off so resolution fails loudly. Which one is the call to make.

Related: #579 (the instance, fixed), #578 (same theme — a make step failing without saying why), #531, #503, #510 (build/supply-chain hygiene guards), #441.


From the pm-triage all status sweep over 681487aa..a5d78257 (the September dependency PRs #570/#573/#574/#579); validated by code-read against a5d78257 on 2026-09-10.

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

    area/infraCI, build, deploy, Docker, releasechore

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions