Skip to content

fix(dev): Share one @sentry/junior copy between the app and dashboard - #2363

Merged
thomasjiangcy merged 1 commit into
mainfrom
fix/dev-dashboard-shared-junior
Oct 29, 2026
Merged

thomasjiangcy merged 1 commit into
mainfrom
fix/dev-dashboard-shared-junior

Conversation

@sentry-junior

@sentry-junior sentry-junior Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Under pnpm dev, a dashboard message can stay stuck. The default JUNIOR_STATE_ADAPTER=memory makes this happen. The web input saves the pending message in one memory store. The queue consumer reads a different memory store, finds no work, and returns no_work. Because of that, conversation.work.lease.acquired is not logged.

Root cause

The app and the dashboard load two copies of the @sentry/junior module in the same process. Each copy has its own stateAdapter singleton (packages/junior/src/chat/state/adapter.ts, let stateAdapter).

  • dev-server.mjs links the injected dashboard dist to packages/junior-dashboard/dist. Node resolves symlinks to their real path. So the dashboard's import "@sentry/junior/api" (createJuniorApi) resolves from packages/junior-dashboard/node_modules/@sentry/junior. That is the injected copy @sentry+junior@file+packages+junior_@types+node@25.9.1_react-dom@19.2.6_react@19.2.6__react@19.2.6_vitest@4.1.12. It is a real copy, not a link.
  • syncInjectedPackageDist linked only the @sentry/junior copies that resolve from the workspace root and apps/example. Those copies run packages/junior/dist.
  • So the request handler (in the dashboard's copy) and the dev consumer (in the app's copy) each make their own memory state.

This change also links the @sentry/junior copy that the dashboard resolves. Then both sides resolve to packages/junior/dist and share one module instance.

Evidence

I used temporary logs that print an id for each memory state instance, process.pid, threadId, and import.meta.url. I also used a temporary in-process queue, because the Vercel queue send needs credentials. The diff does not include either one. I sent the message with POST /api/conversations.

Before (main at 995d44e):

memory state created id=69w59y pid=4049 thread=1 module=.../packages/junior/dist/adapter-*.js
memory state created id=7j783o pid=4049 thread=1 module=.../node_modules/.pnpm/@sentry+junior@..._vitest@4.1.12/node_modules/@sentry/junior/dist/adapter-*.js
web-input saved status=appended state=7j783o module=.../@sentry+junior@..._vitest@4.1.12/.../dist/web-input-*.js
worker read pending=0 state=69w59y module=.../packages/junior/dist/worker-*.js

Both instances have the same pid and thread. This rules out a worker thread or a separate process. It also rules out a Nitro restart, because both instances were alive at the same time.

After (this branch, on 9818055): before the run, I replaced the injected dist link with a real copy. pnpm dev made the link again (.../_vitest@4.1.12/node_modules/@sentry/junior/dist -> packages/junior/dist).

memory state created id=kydof4 pid=14815 thread=1 module=.../packages/junior/dist/adapter-*.js   (only instance)
web-input saved status=appended state=kydof4 module=.../packages/junior/dist/web-input-*.js
worker read pending=1 state=kydof4 module=.../packages/junior/dist/worker-*.js
INF conversation.work.lease.acquired gen_ai.conversation.id=local:web:95e6b6916dbdda1498b89a58

Checks

  • Local pnpm dev repro, before and after, as shown above
  • prettier --check scripts/dev-server.mjs: pass
  • node --check scripts/dev-server.mjs: pass

Not verified

  • I did not test the real Vercel queue path, because I had no OIDC token. Earlier reports saw the same stall with both the Vercel queue dev path and a BullMQ queue, which fits a cause that does not depend on the queue.
  • I did not test restarts. watchDistForNitroRestart restarts Nitro after each dist rebuild, and that still erases memory state. That is a separate cause, and this PR does not change it.

via @thomasjiangcy.

--

View Junior Session [Sentry]

Co-Authored-By: Thomas Jiang <20501235+thomasjiangcy@users.noreply.github.com>
@vercel

vercel Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
junior-docs Ready Ready Preview Oct 29, 2026 2:49pm UTC

Request Review

@thomasjiangcy
thomasjiangcy merged commit a8ddb35 into main Oct 29, 2026
45 checks passed
@thomasjiangcy
thomasjiangcy deleted the fix/dev-dashboard-shared-junior branch October 29, 2026 15:15

This branch was successfully deployed

1 active deployment
Preview – junior-docs — aeac89cb Deployed Oct 29, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: medium PR risk score: medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant