Skip to content

Troubleshooting JavaScript / Node.js projects

This page covers the problems that come up after connecting a JavaScript or Node.js project with @patchstack/connect: a Patchstack Connector that never appears, a widget that appears twice, a published site still serving an old integration, a build that broke after a config change, a Connect install stuck on an old version, and an update that will not take because the package manager is holding the release back.

Every section ends with a prompt you can paste into your site builder’s AI chat. The prompts are deliberately explicit about proving the result, because builder assistants otherwise tend to report the version they remember, or stop after editing one file.

AI builders differ in which package manager they use and which controls they expose. Prepend the snippet for your platform to any prompt below.

Lovable

This is a Lovable project. Inspect the existing lockfile before installing
anything. Lovable projects often use Bun; if bun.lock or bun.lockb exists, use
Bun and do not create a package-lock.json beside it.

GoDaddy Airo

This is a GoDaddy Airo project. Make the changes in the project workspace and
use its existing package manager. If Airo does not expose the required install
or build control, tell me exactly which step is unavailable instead of
reporting that the task is complete.

Hostinger Horizons

This is a Hostinger Horizons project. Use its existing package manager and allow
the dependency install and full production build to finish before checking the
result; do not treat a slow build as a failed one.

Anything else, or not sure

First identify this project's package manager from its lockfile and use that
same package manager for every command. Do not create a second lockfile.

The visitor-facing Report a vulnerability button does not appear until the site is connected to a Patchstack account. If you installed Connect and never saw it, that is usually the reason rather than a broken install — work through these in order.

  1. Connect the site to your account. While the site is unclaimed the widget shows a one-time “Connect this website” panel instead of the report button. Sign in through that panel — on your preview it is already on the page — and the button takes its place permanently. The dashboard link and npx @patchstack/connect claim do the same thing from a browser or a terminal.

    To skip the onboarding entirely and always show the report form, set data-build-mode="false" on the script tag:

    <script
    src="https://cdn.patchstack.com/patchstack-widget.js"
    data-site-uuid="YOUR-SITE-UUID"
    data-build-mode="false"
    defer
    ></script>
  2. Open the widget as the site owner. On a published build the connect panel and the owner “Log in” link are hidden from visitors, so neither is a sign the install failed. Load any page of your site with #patchstack appended to the URL:

    https://your-site.com/#patchstack

    That reveals the owner log-in even on a live production build, and it works from any device or network. ?patchstack in the query string does the same thing.

  3. Check the script tag actually shipped. View source on the published page (not the builder preview) and confirm there is exactly one script loading https://cdn.patchstack.com/patchstack-widget.js, with data-site-uuid set to the UUID from your committed .patchstackrc.json.

  4. Check the site UUID is a literal value. The UUID must be written into the HTML. Reading it from VITE_*, NEXT_PUBLIC_*, or another environment-only variable that is not defined at build time leaves the attribute empty and the widget silent. The site UUID is public by design — it ships in client-side HTML and is not a secret.

  5. Check the widget was not disabled. "widget": false in .patchstackrc.json turns off all widget management, and the next scan will not re-add the tag.

  6. Check the browser console. A Content Security Policy that omits cdn.patchstack.com from script-src, or a content blocker, will stop the script from loading. Both show up as an error on the live page.

Use this when the widget works in the builder preview but is absent from the published site.

Please diagnose why the Patchstack Connector works in preview but is missing from
the published site.
1. Use the latest @patchstack/connect release from npm.
2. Confirm the root page contains exactly one Connect-managed script from
https://cdn.patchstack.com/patchstack-widget.js with data-site-uuid set from
the public .patchstackrc.json value.
3. Do not read the site UUID from VITE_*, NEXT_PUBLIC_*, or another
environment-only variable.
4. Run the Connect setup/scan flow and the complete production build,
including mark-build where the project scripts require it.
5. Inspect the generated production output — not only source files — and verify
that the widget script and window.__PATCHSTACK_PROD__ marker are present.
6. Publish that verified output, then check the live page and browser console
for the first concrete error.
Please make the fix and show the production evidence. Thank you.

Your source can be correct while the builder or CDN is still serving an older artifact. Confirm the live URL — not the preview — is loading the current script, and compare the version the widget reports in each.

The widget shows its version in the owner dashboard. If preview and live disagree, the deployment is stale, not the code.

Please verify that the published site is actually serving the newest Patchstack
integration rather than an older build artifact.
1. Confirm @patchstack/connect matches the newest release the project's
package manager will install. A release published in the last 24 hours may
be held back — see the section below.
2. Confirm the site loads the Patchstack CDN script rather than a copied local
patchstack-widget.js file.
3. Run a clean production build through the project's normal build command and
wait for it to finish.
4. Republish the new output and invalidate only the relevant builder/deployment
cache if the platform exposes that control.
5. On the live URL, inspect the Network response for patchstack-widget.js and
the version shown by the widget. Compare that with preview and report both
values.
Please do not stop at a source-code check; verify the live deployment.
Thank you.

Site builders often resolve @patchstack/connect from cached package metadata and land on an older release. Check what npm actually has:

Terminal window
npm view @patchstack/connect version

Then compare it against the lockfile, not package.json. The lockfile records what is installed; package.json records what was asked for, and the two can disagree — see the next section. If they differ, install @patchstack/connect@latest with the package manager that matches your lockfile.

Please update @patchstack/connect from the official npm registry. Please do not
rely on a remembered or cached version.
1. Query npm for the current dist-tag with: npm view @patchstack/connect version.
2. Install @patchstack/connect@latest as a regular dependency with the package
manager already used by this project.
3. Confirm the exact installed version in the LOCKFILE, not package.json, and
with @patchstack/connect --version.
4. If the lockfile did not move to the version you asked for, check whether this
project holds back newly published packages (for example minimumReleaseAge in
bunfig.toml) and tell me the version it settled on and why.
5. Run the project's complete production build.
6. Tell me the registry version, the installed version from the lockfile, files
changed, and the final build result.
Please make the changes and verify them. Thank you.

The update keeps coming back after I update

Section titled “The update keeps coming back after I update”

Some platforms hold a newly published package for a day before they will install it. Lovable is one: every project it generates carries a bunfig.toml with

[install]
minimumReleaseAge = 86400

which tells Bun to skip any version published in the last 24 hours. Ask for one of those and the install reports success, package.json shows the new number, and the lockfile stays exactly where it was.

This is a supply-chain guard, and a reasonable one — a package published minutes ago has had no time to be noticed if it was published by someone who should not have been able to. We do not suggest turning it off.

To see what actually happened, open your lockfile (bun.lock, package-lock.json, pnpm-lock.yaml) and find @patchstack/connect. That number is the one that counts. If it is behind package.json, the release you asked for is still inside the hold window, and the install will pick it up on its own the next time the project is built after the window passes.

Patchstack allows for this. The update notice in your dashboard and in the widget compares what you have installed against the newest release your package manager will actually accept, so it does not ask you to install something that is being held back — and when a newer release exists but is still held, the update screen says so rather than treating it as something you have failed to do.

Connect uses two config files with different jobs, and mixing them up breaks the build:

FileCommit it?Holds
.patchstackrc.jsonYesThe public siteUuid and non-secret settings such as widget
.patchstackrc.local.jsonNo — gitignore itapiKey only

The API key can also come from the PATCHSTACK_API_KEY environment variable. Never import it into browser code and never move it into the public config.

Please diagnose and fix the Patchstack build after the config-file update.
1. Update @patchstack/connect to the latest npm version first, even if it was
released within the last 24 hours.
2. Search the entire project for .patchstackrc.json and
.patchstackrc.local.json, including build scripts and generated integration
code.
3. Keep the public siteUuid and non-secret settings in committed
.patchstackrc.json.
4. Keep apiKey only in gitignored .patchstackrc.local.json or
PATCHSTACK_API_KEY. Never import that secret into browser code or move it
into the public config.
5. Fix any stale code path that still expects the credential only in
.patchstackrc.json, while preserving the site UUID.
6. Run Patchstack status, scan, and the complete production build. Report the
root cause, exact files changed, and build output.
Please complete and verify the fix. Thank you.

Two shield buttons stacked in the corner, sometimes one opening the owner log-in and the other the report form, mean the widget script ran twice on that page. They often sit on exactly the same pixel, so the second one only shows when a panel opens or the layout shifts.

The widget keeps one floating launcher per page on its own:

  • A second copy loaded by the same document is ignored, with a [PatchstackWidget] warning in the browser console.
  • A copy inside a page of your own site that the shell shows in an <iframe> stands down as well, with a console message. Connect’s mark-build step stamps every built HTML file, so an embedded static page carries the tag too; that copy is harmless and you can leave it.

What still needs your attention is a second tag that you, or the builder’s AI, added by hand. It usually lives in a component, a layout, or a runtime useEffect that appends the script. Keep exactly one tag, in the root shell.

Count the copies on the published page from the browser console:

document.querySelectorAll('script[src*="patchstack-widget"]').length // want 1
document.querySelectorAll('#patchstack-widget-host').length // want 1

If the page embeds another page of your site in an <iframe>, run the same two lines inside that frame (pick it in the console’s context dropdown). One host in the shell and none in the frame is the expected result.

Please make sure the Patchstack Connector is loaded exactly once on this site.
1. Search the entire project - source files, layouts, components, and static
HTML under public/ - for "patchstack-widget.js" and list every place that
loads it.
2. Keep exactly one <script> tag: the Connect-managed one in the root shell
(index.html, or the root layout for Next.js / TanStack Start / Remix). It
must carry data-site-uuid with the value from the committed
.patchstackrc.json.
3. Remove every other copy that was added by hand: in components, in layouts,
and in code that appends the script at runtime. If a component must load it
at runtime, call destroy() on the returned widget in the effect cleanup.
4. Leave the tag that @patchstack/connect writes into static HTML pages during
mark-build; the widget ignores it when that page is shown inside the shell.
5. Run the complete production build, publish it, open the live site, and
confirm a single launcher is visible and the browser console shows no
"[PatchstackWidget] A floating widget is already on this page" warning.
Please make the changes and show me the list from step 1 and the console
check from step 5. Thank you.
  • npx @patchstack/connect guide prints a project-aware checklist of what is present and what is missing.
  • npx @patchstack/connect status re-prints the site UUID and dashboard link.
  • Pulse sites overview explains what a connected site looks like in the Patchstack App, including how to tell whether it is reporting.