Skip to content

fix(plugin-federation): add .js extension to the @apollo/subgraph subpath import - #1662

Merged
hayes merged 1 commit into
mainfrom
claude/latest-repo-issue-rl4zpu
Sep 3, 2026
Merged

fix(plugin-federation): add .js extension to the @apollo/subgraph subpath import#1662
hayes merged 1 commit into
mainfrom
claude/latest-repo-issue-rl4zpu

Conversation

@hayes

@hayes hayes commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Fixes #1661.

The bug

packages/plugin-federation/src/schema-builder.ts imports @apollo/subgraph/dist/types with no file extension. Node's ESM resolver does not guess extensions for package subpaths, and @apollo/subgraph publishes no exports map that would remap it, so importing @pothos/plugin-federation from an ESM package throws at startup on 4.4.3 through 4.5.0:

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '.../@apollo/subgraph/dist/types'
imported from .../@pothos/plugin-federation/esm/schema-builder.js
Did you mean to import "@apollo/subgraph/dist/types.js"?

CJS is unaffected — require() still resolves extensions, so lib/ works on both versions.

Why it regressed

Up to 4.4.2 the ESM build appended extensions via scripts/esm-transformer.ts, which resolved bare subpaths through require.resolve and rewrote them. The TypeScript 7 migration (a32b270) replaced that step with extensions written in source and enforced by biome's useImportExtensions. That rule only covers relative imports, so the relative specifiers in this file were updated and the bare subpath on line 2 was left as it was.

The fix

One character of behavior: @apollo/subgraph/dist/types@apollo/subgraph/dist/types.js. dist/types.js and its sibling dist/types.d.ts both exist in the published package, so CJS, ESM, and type resolution all keep working.

Other occurrences

I swept every packages/*/src tree for non-relative subpath specifiers. @apollo/subgraph/dist/types was the only one. The other subpath imports in the repo are all in examples/ and website/ (next/*, drizzle-orm/*, @apollo/server/*, fumadocs-*), which are not published and whose targets all ship exports maps.

Regression guard

Added packages/plugin-federation/tests/esm-imports.test.ts. For each package subpath imported from src, it reads the target package's manifest: if there is no exports map to remap the subpath, the specifier has to name a file that exists. This is the check biome's rule does not do.

Verification

  • The reproduction from the issue fails on the pre-fix build with the exact error above, and loads cleanly after: node --input-type=module -e "await import('./esm/index.js')" → OK; node -e "require('./lib/index.js')" → OK.
  • The new test fails when the extension is removed and passes with it.
  • pnpm turbo run build --filter='@pothos/plugin-federation...' succeeds; the built esm/ and lib/ output both carry dist/types.js.
  • pnpm vitest --run in packages/plugin-federation: 3 files, 9 tests passed, no type errors.
  • pnpm biome check clean.

One note on running the suite locally: the superGraph test in tests/index.test.ts starts local HTTP servers and fails with a 405 Method Not Allowed if an HTTP proxy is set in the environment. Unsetting the proxy variables makes it pass. Unrelated to this change.

🤖 Generated with Claude Code

https://claude.ai/code/session_01L1YyNQHKx3pmp3zS9f9CMw


Generated by Claude Code

…path import

`esm/schema-builder.js` imported `@apollo/subgraph/dist/types` with no file
extension. Node's ESM resolver does not guess extensions for package subpaths,
and `@apollo/subgraph` publishes no `exports` map to remap it, so importing
`@pothos/plugin-federation` from an ESM package threw ERR_MODULE_NOT_FOUND at
startup on 4.4.3 through 4.5.0. CJS was unaffected because `require()` still
resolves extensions.

Up to 4.4.2 the ESM build appended extensions via scripts/esm-transformer.ts,
which resolved bare subpaths through `require.resolve`. The TypeScript 7
migration replaced that step with extensions written in source and enforced by
biome's useImportExtensions, but that rule only covers relative imports, so this
specifier was left as it was.

Add a test that checks package subpath imports in src against the target
package's manifest: when the package has no `exports` map, the subpath has to
name a file that exists. A sweep of every package's src found no other
occurrence.

Fixes #1661

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L1YyNQHKx3pmp3zS9f9CMw
@changeset-bot

changeset-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: d561d35

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@pothos/plugin-federation Patch
@pothos-examples/federation Patch
@pothos-examples/prisma-federation Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Sep 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
pothos Ready Ready Preview Sep 3, 2026 4:13pm UTC

@pkg-pr-new

pkg-pr-new Bot commented Sep 3, 2026

Copy link
Copy Markdown

Open in StackBlitz

@pothos/core

npm i https://pkg.pr.new/@pothos/core@1662

@pothos/plugin-add-graphql

npm i https://pkg.pr.new/@pothos/plugin-add-graphql@1662

@pothos/plugin-complexity

npm i https://pkg.pr.new/@pothos/plugin-complexity@1662

@pothos/plugin-dataloader

npm i https://pkg.pr.new/@pothos/plugin-dataloader@1662

@pothos/plugin-directives

npm i https://pkg.pr.new/@pothos/plugin-directives@1662

@pothos/plugin-drizzle

npm i https://pkg.pr.new/@pothos/plugin-drizzle@1662

@pothos/plugin-errors

npm i https://pkg.pr.new/@pothos/plugin-errors@1662

@pothos/plugin-example

npm i https://pkg.pr.new/@pothos/plugin-example@1662

@pothos/plugin-federation

npm i https://pkg.pr.new/@pothos/plugin-federation@1662

@pothos/plugin-grafast

npm i https://pkg.pr.new/@pothos/plugin-grafast@1662

@pothos/plugin-mocks

npm i https://pkg.pr.new/@pothos/plugin-mocks@1662

@pothos/plugin-prisma

npm i https://pkg.pr.new/@pothos/plugin-prisma@1662

@pothos/plugin-prisma-utils

npm i https://pkg.pr.new/@pothos/plugin-prisma-utils@1662

@pothos/plugin-relay

npm i https://pkg.pr.new/@pothos/plugin-relay@1662

@pothos/plugin-scope-auth

npm i https://pkg.pr.new/@pothos/plugin-scope-auth@1662

@pothos/plugin-simple-objects

npm i https://pkg.pr.new/@pothos/plugin-simple-objects@1662

@pothos/plugin-smart-subscriptions

npm i https://pkg.pr.new/@pothos/plugin-smart-subscriptions@1662

@pothos/plugin-sub-graph

npm i https://pkg.pr.new/@pothos/plugin-sub-graph@1662

@pothos/plugin-tracing

npm i https://pkg.pr.new/@pothos/plugin-tracing@1662

@pothos/plugin-validation

npm i https://pkg.pr.new/@pothos/plugin-validation@1662

@pothos/plugin-with-input

npm i https://pkg.pr.new/@pothos/plugin-with-input@1662

@pothos/plugin-zod

npm i https://pkg.pr.new/@pothos/plugin-zod@1662

@pothos/tracing-newrelic

npm i https://pkg.pr.new/@pothos/tracing-newrelic@1662

@pothos/tracing-opentelemetry

npm i https://pkg.pr.new/@pothos/tracing-opentelemetry@1662

@pothos/tracing-sentry

npm i https://pkg.pr.new/@pothos/tracing-sentry@1662

@pothos/tracing-xray

npm i https://pkg.pr.new/@pothos/tracing-xray@1662

commit: d561d35

@hayes
hayes merged commit cb07106 into main Sep 3, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Federation plugin: ESM build imports @apollo/subgraph/dist/types without a file extension

2 participants