René's URL Explorer Experiment


Title: Click-to-source sends empty source= and hangs because setDisabledAfterClick(true) runs before reading highlightState.dataSource · Issue #451 · TanStack/devtools · GitHub

Open Graph Title: Click-to-source sends empty source= and hangs because setDisabledAfterClick(true) runs before reading highlightState.dataSource · Issue #451 · TanStack/devtools

X Title: Click-to-source sends empty source= and hangs because setDisabledAfterClick(true) runs before reading highlightState.dataSource · Issue #451 · TanStack/devtools

Description: TanStack Devtools version @tanstack/devtools-vite: 0.7.0 @tanstack/react-devtools: 0.10.5 Framework/Library version react: 19.2.6 Describe the bug and the steps to reproduce it When using the inspect hotkey (Shift+Alt+Cmd) to click a com...

Open Graph Description: TanStack Devtools version @tanstack/devtools-vite: 0.7.0 @tanstack/react-devtools: 0.10.5 Framework/Library version react: 19.2.6 Describe the bug and the steps to reproduce it When using the inspe...

X Description: TanStack Devtools version @tanstack/devtools-vite: 0.7.0 @tanstack/react-devtools: 0.10.5 Framework/Library version react: 19.2.6 Describe the bug and the steps to reproduce it When using the inspe...

Opengraph URL: https://github.com/TanStack/devtools/issues/451

X: @github

direct link

Domain: github.com


Hey, it has json ld scripts:
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Click-to-source sends empty source= and hangs because setDisabledAfterClick(true) runs before reading  highlightState.dataSource","articleBody":"### TanStack Devtools version\n\n@tanstack/devtools-vite: 0.7.0 @tanstack/react-devtools: 0.10.5\n\n### Framework/Library version\n\nreact: 19.2.6\n\n### Describe the bug and the steps to reproduce it\n\n    When using the inspect hotkey (Shift+Alt+Cmd) to click a component, the request to `/__tsd/open-source?source=` is\n   sent with an **empty** `source` parameter, even though the clicked element has a valid `data-tsd-source`\n  attribute. The dev server then hangs the request indefinitely, so the editor never opens.\n\n  This is fully reproducible in any React app using `@tanstack/react-devtools@0.10.x` (which pulls in\n  `@tanstack/devtools@0.12.2`) + `@tanstack/devtools-vite@0.7.0`. I am seeing it across multiple projects with\n  similar stacks.\n\n  ## Versions\n\n  - `@tanstack/devtools@0.12.2`\n  - `@tanstack/react-devtools@0.10.5`\n  - `@tanstack/devtools-vite@0.7.0`\n  - `vite@8.0.14`, `react@19.2.6`, Solid (bundled via devtools)\n\n  ## Reproduction\n\n  1. Add `@tanstack/devtools-vite` to a Vite + React project with a configured `editor`.\n  2. Mount `\u003cTanStackDevtools>` in the app.\n  3. Hold Shift+Alt+Cmd and click any rendered component.\n  4. **Observed:** Network panel shows `GET /__tsd/open-source?source=` (empty value), status `pending` forever.\n  Editor never opens.\n  5. **Expected:** URL should include the clicked element's `data-tsd-source`, server should respond `200`, editor\n  should open.\n\n  I verified the clicked element has a well-formed `data-tsd-source` attribute (matching `/^\\/.+:\\d+:\\d+$/`). On the\n   page tested there were 1869 such elements, 0 empty, 0 malformed.\n\n  ## Root cause\n\n  `packages/devtools/src/.../LGFFJRYV.js` (the inspect overlay component) registers this click handler:\n\n  ```js\n  createEventListener(document, \"click\", (e) => {\n    if (!highlightState.element) return;\n    window.getSelection()?.removeAllRanges();\n    e.preventDefault();\n    e.stopPropagation();\n    setDisabledAfterClick(true);   // \u003c-- step 1\n    if (settings().sourceAction === \"copy-path\") {\n      navigator.clipboard.writeText(highlightState.dataSource).catch(() => {});\n      return;\n    }\n    const baseUrl = new URL(import.meta.env?.BASE_URL ?? \"/\", location.origin);\n    const url = new URL(\n      `__tsd/open-source?source=${encodeURIComponent(highlightState.dataSource)}`,  // \u003c-- step 2\n      baseUrl\n    );\n    fetch(url).catch(() => {});\n  });\n  ```\n\n  `setDisabledAfterClick(true)` flips this memo:\n\n  ```js\n  const isActive = createMemo(\n    () => isHighlightingKeysHeld() && !disabledAfterClick()\n  );\n  ```\n\n  …which makes `isActive()` false, which **synchronously** re-runs the highlight `createEffect`:\n\n  ```js\n  createEffect(() => {\n    if (!isActive()) {\n      resetHighlight();   // \u003c-- sets element=null, dataSource=\"\"\n      return;\n    }\n    ...\n  });\n  ```\n\n  By the time the next line in the click handler reads `highlightState.dataSource`, it is `\"\"`. The constructed URL\n  is `/__tsd/open-source?source=` and is sent.\n\n  ## Compounding server-side bug\n\n  In `@tanstack/devtools-vite` (`utils.js`), the middleware does:\n\n  ```js\n  if (req.url?.includes(\"__tsd/open-source\")) {\n    const source = new URLSearchParams(req.url.split(\"?\")[1]).get(\"source\");\n    if (!source) return;                       // \u003c-- leaves the response hanging\n    const parsed = parseOpenSourceParam(source);\n    if (!parsed) return;                       // \u003c-- same\n    ...\n  }\n  ```\n\n  Both early returns omit both `res.end()` and `next()`, so the connection sits open until the browser times out.\n  This is why users see \"pending\" rather than a quick failure.\n\n  ## Evidence\n\n  Captured at click time on a component whose `data-tsd-source` attribute is\n  `/src/routes/tournaments/$tournament_id/leaderboard.tsx:55:7`:\n\n  ```\n  {\n    \"url\": \"http://localhost:5173/__tsd/open-source?source=\",\n    \"rawSource\": \"\",\n    \"stack\": \"...at HTMLDocument.\u003canonymous> (LGFFJRYV-DaE8v0zr.js:6195:3)\"\n  }\n  ```\n\n  `reqid=101 GET http://localhost:5173/__tsd/open-source?source= [pending]` in the Network panel.\n\n  The clicked element under the cursor at the same instant:\n\n  ```\n  { tag: \"H1\", src: \"/src/routes/tournaments/$tournament_id/leaderboard.tsx:55:7\" }\n  ```\n\n  ## Suggested fix\n\n  **Client (`packages/devtools/.../LGFFJRYV.js`):** capture `dataSource` before mutating signals.\n\n  ```diff\n   createEventListener(document, \"click\", (e) => {\n     if (!highlightState.element) return;\n  +  const source = highlightState.dataSource;   // capture before any setSignal\n     window.getSelection()?.removeAllRanges();\n     e.preventDefault();\n     e.stopPropagation();\n  -  setDisabledAfterClick(true);\n     if (settings().sourceAction === \"copy-path\") {\n  -    navigator.clipboard.writeText(highlightState.dataSource).catch(() => {});\n  +    navigator.clipboard.writeText(source).catch(() => {});\n  +    setDisabledAfterClick(true);\n       return;\n     }\n     const baseUrl = new URL(import.meta.env?.BASE_URL ?? \"/\", location.origin);\n  -  const url = new URL(`__tsd/open-source?source=${encodeURIComponent(highlightState.dataSource)}`, baseUrl);\n  +  const url = new URL(`__tsd/open-source?source=${encodeURIComponent(source)}`, baseUrl);\n     fetch(url).catch(() => {});\n  +  setDisabledAfterClick(true);\n   });\n  ```\n\n  Wrapping the signal write in `batch(() => setDisabledAfterClick(true))` would not help here — the read happens\n  *after* the write, so the value is already reset by the time we read.\n\n  **Server (`packages/devtools-vite/src/utils.ts`):** defensively end the response on bad input instead of leaving\n  the socket open.\n\n  ```diff\n   if (req.url?.includes(\"__tsd/open-source\")) {\n     const source = new URLSearchParams(req.url.split(\"?\")[1]).get(\"source\");\n  -  if (!source) return;\n  +  if (!source) { res.statusCode = 400; res.end(); return; }\n     const parsed = parseOpenSourceParam(source);\n  -  if (!parsed) return;\n  +  if (!parsed) { res.statusCode = 400; res.end(); return; }\n     ...\n   }\n  ```\n\n  ## Workaround for users until fixed\n\n  Add this to your client entry (e.g., `src/main.tsx`) in dev only:\n\n  ```ts\n  if (import.meta.env.DEV) {\n    let lastSource: string | null = null;\n    document.addEventListener('click', (e) => {\n      if (e.shiftKey && e.altKey && (e.metaKey || e.ctrlKey)) {\n        const t = document.elementFromPoint(e.clientX, e.clientY);\n        const el = t?.closest?.('[data-tsd-source]') as HTMLElement | null;\n        if (el) lastSource = el.getAttribute('data-tsd-source');\n      }\n    }, true); // capture phase: runs before the buggy handler\n    const orig = window.fetch;\n    window.fetch = function(input, init) {\n      const url = typeof input === 'string' ? input\n        : input instanceof URL ? input.href\n        : (input as Request).url;\n      if (typeof url === 'string' && url.endsWith('/__tsd/open-source?source=') && lastSource) {\n        const fixed = url + encodeURIComponent(lastSource);\n        lastSource = null;\n        return orig.call(this, fixed, init);\n      }\n      return orig.call(this, input, init);\n    };\n  }\n  ```\n\n### Your Minimal, Reproducible Example - (Sandbox Highly Recommended)\n\nA minimal sandbox isn't practical for this bug.\n\n### Screenshots or Videos (Optional)\n\n_No response_\n\n### Do you intend to try to help solve this bug with your own PR?\n\nMaybe, I'll investigate and start debugging\n\n### Terms & Code of Conduct\n\n- [x] I agree to follow this project's Code of Conduct\n- [x] I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.","author":{"url":"https://github.com/samkuehn","@type":"Person","name":"samkuehn"},"datePublished":"2026-05-25T16:36:58Z","url":"https://github.com/TanStack/devtools/issues/451"}

react-profiling0
react-import-mapreact,react-dom,react-dom/client,react-dom/profiling,react-is,react-reconciler,react/compiler-runtime,react/jsx-dev-runtime,react/jsx-runtime,scheduler@d5750093facf
route-pattern/_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format)
route-controllervoltron_issues_fragments
route-actionissue_layout
fetch-noncev2:9d1c7cb6-452a-253b-91e5-452d983edb97
current-catalog-service-hash81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114
request-id9CF2:268853:2A6E73A:372D13D:6AF9AA74
html-safe-nonce8f61d4145f98f82ee3add65d3e89de5ced8eda5dfc929d71bac6de45e0b895ff
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5Q0YyOjI2ODg1MzoyQTZFNzNBOjM3MkQxM0Q6NkFGOUFBNzQiLCJ2aXNpdG9yX2lkIjoiNDYwNTAxMTA1MjYzMzYzMTM0OCIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9
visitor-hmac4aa7c29e56fb1e7900d64032846862c9d31d55f13e7127382c11cd0034ce6b2b
hovercard-subject-tagissue:4518320325
github-keyboard-shortcutsrepository,issues,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///voltron/issues_fragments/issue_layout
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/TanStack/devtools/451/issue_layout
twitter:imagehttps://opengraph.githubassets.com/5c93c88584c99094f18bf71ba89966de94fa1926ce0803b0f8e738ae02b0ed07/TanStack/devtools/issues/451
twitter:cardsummary_large_image
og:imagehttps://opengraph.githubassets.com/5c93c88584c99094f18bf71ba89966de94fa1926ce0803b0f8e738ae02b0ed07/TanStack/devtools/issues/451
og:image:altTanStack Devtools version @tanstack/devtools-vite: 0.7.0 @tanstack/react-devtools: 0.10.5 Framework/Library version react: 19.2.6 Describe the bug and the steps to reproduce it When using the inspe...
og:image:width1200
og:image:height600
og:site_nameGitHub
og:typeobject
og:author:usernamesamkuehn
hostnamegithub.com
expected-hostnamegithub.com
None612d3e6ffd693e7ea8d9fcf452370995872baef31d825b1fedef704cd3d24ac7
turbo-cache-controlno-preview
go-importgithub.com/TanStack/devtools git https://github.com/TanStack/devtools.git
octolytics-dimension-user_id72518640
octolytics-dimension-user_loginTanStack
octolytics-dimension-repository_id1026402761
octolytics-dimension-repository_nwoTanStack/devtools
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id1026402761
octolytics-dimension-repository_network_root_nwoTanStack/devtools
turbo-body-classeslogged-out env-production page-responsive
disable-turbofalse
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
release072e34035c13c31543fba9f025cbbbda4210dae4
ui-targetfull
theme-color#1e2327
color-schemelight dark
react-app-nameissues

Links:

Skip to contenthttps://github.com/TanStack/devtools/issues/451#start-of-content
https://github.com/
Sign inhttps://github.com/login?return_to=https%3A%2F%2Fgithub.com%2FTanStack%2Fdevtools%2Fissues%2F451
GitHubRepository hosting, code review, and collaborationhttps://github.com/platform
CopilotAI coding agent for tasks, projects, and automated workhttps://github.com/features/copilot
ActionsCI/CD and automationhttps://github.com/features/actions
Code QualityQuality analysis, fixes, and enforcementhttps://github.com/features/code-quality
CodespacesCloud development environmentshttps://github.com/features/codespaces
Code SecurityVulnerability detection and remediationhttps://github.com/security/advanced-security/code-security
Secret ProtectionSecret scanning and leak preventionhttps://github.com/security/advanced-security/secret-protection
All Featureshttps://github.com/features
Documentationhttps://docs.github.com/en
Traininghttps://learn.github.com/skills
Certificationshttps://learn.github.com/credentials
Build with Copilothttps://github.com/features/ai
Customize Copilothttps://docs.github.com/en/copilot/how-tos/copilot-on-github/customize-copilot/customize-copilot-overview
Integrationshttps://github.com/marketplace
Trending reposhttps://github.com/trending
GitHub Sponsorshttps://github.com/open-source/sponsors
Developer articleshttps://github.com/resources/articles
ChangelogYour source for the latest features, improvements, and fixes across GitHub products, all in one place.https://github.blog/changelog/
Enterpriseshttps://github.com/enterprise
Teamhttps://github.com/team
Startupshttps://github.com/enterprise/startups
Nonprofitshttps://github.com/solutions/industry/nonprofits
Healthcarehttps://github.com/solutions/industry/healthcare
Financial serviceshttps://github.com/solutions/industry/financial-services
Manufacturinghttps://github.com/solutions/industry/manufacturing
Governmenthttps://github.com/solutions/industry/government
See all industrieshttps://github.com/solutions/industry
Why GitHubhttps://github.com/why-github
Customer Storieshttps://github.com/customer-stories
Business insightshttps://github.com/solutions/executive-insights
Trust Centerhttps://github.com/trust-center
GitHub Advanced SecurityEnterprise-grade code securityhttps://github.com/security/advanced-security
Copilot for businessEnterprise-grade AI featureshttps://github.com/features/copilot/copilot-business
Premium SupportEnterprise-grade 24/7 supporthttps://github.com/enterprise/premium-support
Documentationhttps://docs.github.com/en
Resource centerhttps://github.com/resources
Bloghttps://github.blog/
Events & webinarshttps://github.com/resources/events
Community Forumhttps://github.com/orgs/community/discussions
Customer Storieshttps://github.com/customer-stories
Integrationshttps://github.com/marketplace
Customer supporthttps://help.github.com/
Traininghttps://learn.github.com/skills
GitHub Statushttps://www.githubstatus.com/
Abouthttps://github.com/about
Partnershttps://github.com/partners
Changeloghttps://github.blog/changelog/
GitHub UniverseThe event for developers, by developers — talks, workshops, and what’s next for GitHub.https://githubuniverse.com/
Pricinghttps://github.com/pricing
Sign inhttps://github.com/login?return_to=https%3A%2F%2Fgithub.com%2FTanStack%2Fdevtools%2Fissues%2F451
Sign uphttps://github.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fvoltron%2Fissues_fragments%2Fissue_layout&source=header-repo&source_repo=TanStack%2Fdevtools
Reloadhttps://github.com/TanStack/devtools/issues/451
Reloadhttps://github.com/TanStack/devtools/issues/451
Reloadhttps://github.com/TanStack/devtools/issues/451
TanStackhttps://github.com/TanStack
devtoolshttps://github.com/TanStack/devtools
Codehttps://github.com/TanStack/devtools
Issues24 (24)https://github.com/TanStack/devtools/issues
Pull requests25 (25)https://github.com/TanStack/devtools/pulls
Discussionshttps://github.com/TanStack/devtools/discussions
Actionshttps://github.com/TanStack/devtools/actions
Security and qualityhttps://github.com/TanStack/devtools/security
Insightshttps://github.com/TanStack/devtools/pulse
https://github.com/TanStack/devtools
New issuehttps://github.com/login?return_to=https://github.com/TanStack/devtools/issues/451
New issuehttps://github.com/login?return_to=https://github.com/TanStack/devtools/issues/451
Click-to-source sends empty source= and hangs because setDisabledAfterClick(true) runs before reading highlightState.dataSourcehttps://github.com/TanStack/devtools/issues/451#top
https://github.com/samkuehn
samkuehnhttps://github.com/samkuehn
on May 25, 2026https://github.com/TanStack/devtools/issues/451#issue-4518320325
https://github.com/djpremier
djpremierhttps://github.com/djpremier
on Jun 8, 2026https://github.com/TanStack/devtools/issues/451#issuecomment-4651080907
#442 (comment)https://github.com/TanStack/devtools/pull/442#issuecomment-4522928065
@AlemTuzlakhttps://github.com/AlemTuzlak
https://github.com/AlemTuzlak
AlemTuzlakhttps://github.com/AlemTuzlak
on Jun 8, 2026https://github.com/TanStack/devtools/issues/451#issuecomment-4652306202
@djpremierhttps://github.com/djpremier
AlemTuzlakhttps://github.com/AlemTuzlak
on Oct 29, 2026https://github.com/TanStack/devtools/issues/451#event-34601795756
fix(devtools-bundler-core): open source files outside cwd and end bad…https://github.com/TanStack/devtools/commit/df1464cdca80efa98b98930790046828255624ef
df1464chttps://github.com/TanStack/devtools/commit/df1464cdca80efa98b98930790046828255624ef
Sign up for freehttps://github.com/signup?return_to=https://github.com/TanStack/devtools/issues/451
Sign in to commenthttps://github.com/login?return_to=https://github.com/TanStack/devtools/issues/451
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.