Skip to content

Development target of the api's #runtime/v1/* import is not a valid package target #1653

Open

Description

@joshunrau

The development target of the #runtime/v1/* subpath import in apps/api/package.json is ../../runtime/v1/dist/*. Node's resolver accepts an imports target only if it is package-relative (./…) or a bare specifier, so Node rejects this one: under --conditions=development, resolving #runtime/v1/... throws ERR_INVALID_PACKAGE_TARGET. Production uses the default target (./dist/runtime/v1/*), which is valid and unaffected. In pnpm dev the main thread does not hit the error either, because libnest dev registers @swc-node/register, whose oxc-resolver accepts the ../ target. Two places do hit it:

  • Worker threads under pnpm dev. Module hooks registered in the main thread are not inherited, so export-worker.js throws when importing #runtime/v1/.... It works only because of a try/catch that falls back to @opendatacapture/runtime-v1/....
  • Vitest. InstrumentsModule's __resolveImport cannot be exercised under the development condition.

The effect is limited to tooling and dev, but the target is invalid by spec, works only because of one resolver's leniency, and has already led to a workaround in export-worker.js.

Where

  • apps/api/package.json:72-76:

    "imports": {
      "#runtime/v1/*": {
        "development": "../../runtime/v1/dist/*",
        "default": "./dist/runtime/v1/*"
      }
    }
  • apps/api/src/instruments/instruments.module.ts:15-20: import.meta.resolve(specifier.replace(/^\/runtime/, '#runtime')).

  • apps/api/src/instrument-records/export-worker.js:9-16: the fallback added for this ("we need to resolve import correctly in development").

The target has had this shape since 20de0ee1c (libnest rewrite).

Reproduce

From apps/api on Node 24.15:

node --conditions=development --input-type=module -e 'console.log(import.meta.resolve("#runtime/v1/@opendatacapture/runtime-internal/index.js"))'

Actual: ERR_INVALID_PACKAGE_TARGET: Invalid "imports" target "../../runtime/v1/dist/*" defined for '#runtime/v1/*'.
Expected: file:///…/runtime/v1/dist/@opendatacapture/runtime-internal/index.js.

The same call succeeds when the swc-node hook is registered in the same thread, and fails in a Worker spawned from that thread.

Tests

apps/api/src/instruments/__tests__/instruments.module.spec.ts, test "should resolve a runtime import to the built runtime, even under the development condition", is marked it.fails. Change it to it once the target is fixed. Its comment says pnpm dev is affected; correct that, since the main thread under pnpm dev resolves the target through swc-node.

Suggested fix

Change the development target to the bare specifier @opendatacapture/runtime-v1/*. The api already depends on that package, and its exports maps ./* to ./dist/*. A scratch package using this target resolved to the same runtime/v1/dist/... URL under plain Node with --conditions=development. The try/catch fallback in export-worker.js can then be removed.

Found while raising unit test coverage in #1632.

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: APIapps/api (NestJS backend, Prisma models, CASL permissions)BugType: existing behavior is wrongDifficulty: LowIsolated change, about 2 hours or lessPriority: LowNice to have, cosmetic or speculative

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions