Skip to content

[Bug]: npx t3@0.0.23 startup crash from mixed Effect dependency versions #2667

Description

@ben-vargas

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

On macOS with Node 24 / npm 11, run the published CLI through npm exec or npx from a clean install context:

rm -rf /tmp/t3-asEffect-cache /tmp/t3-asEffect-state
npm --cache /tmp/t3-asEffect-cache exec --package t3@0.0.23 -- \
  t3 serve --base-dir /tmp/t3-asEffect-state --host 127.0.0.1 --port 3999 --no-browser

I see the same behavior with the current nightly:

rm -rf /tmp/t3-nightly-asEffect-cache /tmp/t3-nightly-asEffect-state
npm --cache /tmp/t3-nightly-asEffect-cache exec --package t3@nightly -- \
  t3 serve --base-dir /tmp/t3-nightly-asEffect-state --host 127.0.0.1 --port 3999 --no-browser

This also reproduces with a fresh state directory, so it does not appear to be a migrated local state problem.

Expected behavior

The published t3 CLI should start the server successfully from a clean npx / npm exec install, using the same Effect package family versions that the monorepo catalog and published package metadata intend.

Actual behavior

The CLI exits immediately during startup:

[14:04:58.797] ERROR (#1): TypeError: state.value.asEffect is not a function

The failure appears to come from npm dependency resolution producing a mixed Effect runtime. In a clean npm exec --package t3@0.0.23 install, the package metadata declares/publishes:

"effect": "4.0.0-beta.59",
"@effect/platform-node": "4.0.0-beta.59",
"overrides": {
  "@effect/platform-node-shared": "4.0.0-beta.59",
  "effect": "4.0.0-beta.59"
}

But the actual install tree can still resolve a root/transitive @effect/platform-node-shared@4.0.0-beta.66 / effect@4.0.0-beta.66 alongside t3's nested effect@4.0.0-beta.59. My understanding is that npm does not apply a dependency package's own overrides as if they were root-project overrides, so the published guard in t3/package.json is not enough for the npx / npm exec --package t3@... install shape.

I verified the version-skew hypothesis by forcing the Effect packages at the exec root. This starts successfully:

rm -rf /tmp/t3-forced-effect-cache /tmp/t3-forced-effect-state
npm --cache /tmp/t3-forced-effect-cache exec \
  --package t3@0.0.23 \
  --package effect@4.0.0-beta.59 \
  --package @effect/platform-node-shared@4.0.0-beta.59 \
  -- \
  t3 serve --base-dir /tmp/t3-forced-effect-state --host 127.0.0.1 --port 3999 --no-browser

The same forced-package workaround also makes the current t3@nightly start.

Impact

Blocks work completely

Version or commit

t3@0.0.23 / tag v0.0.23 (3c32bc8fd1f5970e65988e36937cb8e2921437f9)

Also reproduced with t3@0.0.24-nightly.20260512.271.

Environment

macOS, Node v24.14.0, npm 11.9.0, launching via npm exec --package t3@... / npx.

Logs or stack traces

$ npm --cache /tmp/t3-asEffect-cache exec --package t3@0.0.23 -- \
  t3 serve --base-dir /tmp/t3-asEffect-state --host 127.0.0.1 --port 3999 --no-browser

[13:48:33.120] ERROR (#1): TypeError: state.value.asEffect is not a function

Clean install tree evidence:

t3@0.0.23
  effect@4.0.0-beta.59

root/transitive install also contains:
  effect@4.0.0-beta.66
  @effect/platform-node-shared@4.0.0-beta.66

Related issue/PR search:

Screenshots, recordings, or supporting files

None.

Workaround

Force the Effect packages at the npm exec root to the version declared by the published t3 package:

effect_version="$(npm view t3@latest dependencies.effect)"
npm exec \
  --package "t3@latest" \
  --package "effect@${effect_version}" \
  --package "@effect/platform-node-shared@${effect_version}" \
  -- \
  t3 serve --host 127.0.0.1 --port 3773 --no-browser

A durable fix might need the published package/install path to avoid relying on dependency-level overrides, or otherwise ensure @effect/platform-node-shared cannot float beyond the Effect version used by the bundled CLI.

Activity

  1. jameshaworthcs commented on May 13, 2026

    @jameshaworthcs

    Verified that #2676 fixes this.

    Built t3 from f92e1e1b, packed with catalog refs resolved and without the overrides field (npm only honors overrides from the install root, so this mirrors how a downstream npx t3 / npm exec --package t3 install resolves). Installed the tarball into an empty directory with a clean npm cache:

    $ npm ls effect
    t3-install@1.0.0 /tmp/t3-install
    └─┬ t3@0.0.23
      ├─┬ @effect/platform-bun@4.0.0-beta.59
      │ └── effect@4.0.0-beta.59 deduped
      ├─┬ @effect/platform-node-shared@4.0.0-beta.59
      │ └── effect@4.0.0-beta.59 deduped
      ├─┬ @effect/platform-node@4.0.0-beta.59
      │ └── effect@4.0.0-beta.59 deduped
      ├─┬ @effect/sql-sqlite-bun@4.0.0-beta.59
      │ └── effect@4.0.0-beta.59 deduped
      └── effect@4.0.0-beta.59
    

    Single effect, deduped everywhere. t3 serve --base-dir … --no-browser reaches Listening on … cleanly with no state.value.asEffect crash.

    Mechanism: pre-fix, npm hoisted @effect/platform-node-shared@4.0.0-beta.66 to satisfy the ^4.0.0-beta.59 caret range declared by both @effect/platform-node and @effect/platform-bun. That beta.66 package's effect: ^4.0.0-beta.66 peer then dragged in the second effect copy. The exact pin on @effect/platform-node-shared added in #2676 blocks that float, so the higher-effect peer never enters the graph.

    Tested on WSL2 / Linux, Node 22.22.1, npm 10.9.4. The forced-package workaround in the issue body shouldn't be needed once a release containing f92e1e1b ships.

  2. ben-vargas commented on May 13, 2026

    @ben-vargas
    ContributorAuthor

    Thanks for pointing that out @jameshaworthcs - cloned with that commit and confirmed it will be fixed when released in next latest and nightly release tags. Closing as completed.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions