Verify your install
Run the Botscent check against your site, read each line, and fix what fails.
npx botscent check tests a Botscent install from outside. It requests your page, opens the page in a local Chrome, and reads your project. Run it at the end of every install, and again after each fix.
1. Start the site
Start the site that you installed Botscent in. A local server and a deployed site both work.
2. Run the check
From the project's directory, run the check against the URL of one page:
npx botscent check http://localhost:3000/The check prints one line for each check, then a summary line.
3. Read the output
This output comes from a run against the Botscent site, which runs Next.js on Vercel:
botscent check 0.0.0: https://botscent.nibnalin.me/
PASS reachable 200, text/html; charset=utf-8
PASS server-half entry 1;botscent-check;1790995621428;ua.declared-agent-token on check's own request
PASS entry fresh (+0.9 s) and single
PASS no-store Cache-Control: no-store
PASS person no entry on a request without agent evidence
PASS cache cached HTML (Age: 1335), decorated after the cache lookup
PASS page-script botscent 0.0.0 started 852 ms after navigation
PASS page-verdict agent [browser.webdriver-flag, ua.headless-chrome] under automation, as expected
PASS transport the page received 1;;1790995622694;ua.headless-chrome
PASS probes 10 ok
PASS csp no policy
SKIPPED script no botscent.js tag; the page half is bundled, or absent
PASS stack Next.js; on Vercel
SKIPPED adapters not run inside a project (pass --project <dir>)
Installed.Each line gives the outcome, the check id and what the check observed. A line that is not a pass also gives the likely cause and the fix.
The last line is Installed., Unverified: neither half could be confirmed. or a Broken: line with the number of failed checks.
4. Fix each failure
If a line says FAIL, apply the fix that the line gives. Then run the check again. For the common failures, see Common fixes.
If a line says UNKNOWN, read its likely cause. At an origin server with the transport off, an UNKNOWN line for server-half is expected.
What the check does
The check does 3 things, in this order:
- It requests the page as a navigation, with the user agent
botscent-check/<version>. Then it requests the page again at once, with an empty user agent. If a cache stored the first response, the cache serves the stored copy to the second request. - It opens the page in a local Chrome or Chromium over the DevTools protocol. It reads the page verdict, the page half's diagnostics, the
Server-Timingentries, console errors and Content Security Policy violations. - It reads the project in the current directory, or in the directory that
--projectgives. It finds the frameworks and everybotscentimport. It compares a Next.js proxy or a Vercel middleware file with its version at gitHEAD.
Chrome under the DevTools protocol sets the webdriver flag, as any automation does. So the page half reports an agent in the check's browser, with the reason browser.webdriver-flag. The page-verdict check expects this.
Options
| Option | What it does |
|---|---|
--origin <url> | Also requests the origin directly, to find a hop that removes Server-Timing. |
--project <dir> | Reads this project. The default is the current directory, if it has a package.json. |
--chrome <path> | Drives this Chrome or Chromium. The default is a browser that the check finds, or CHROME_PATH. |
--no-browser | Skips the checks that need a browser. |
--json | Prints the checks as JSON. |
--report | Adds a block to paste into an issue. |
Outcomes
| Outcome | Meaning |
|---|---|
pass | The check observed what a working install gives. |
fail | The check observed a broken install. The line gives the likely cause and the fix. |
unknown | The check cannot tell from outside whether the install is correct. The line gives the likely cause. |
skipped | The check had nothing to test, for example because no browser was found. |
The checks
The checks run and print in this order:
| Check | What it tests |
|---|---|
reachable | The page answers with a status below 400. A challenge page from the site's own protection gives unknown. |
server-half | The check's own request gets a botscent entry in Server-Timing, and the entry names botscent-check. |
entry | There is one entry, and it was written between 10 s before and 120 s after the check's request. |
no-store | The response that carries the entry also has Cache-Control: no-store. |
person | The request with an empty user agent gets no entry. |
cache | If people get cached HTML, the cached HTML carries no botscent entry. |
page-script | The page half is on the page and has started. |
page-verdict | Under automation, the page verdict is agent with the reason browser.webdriver-flag. |
transport | The page received the entry from the server half. |
probes | No probe of the page half failed. A probe that the browser does not support is a pass. |
csp | The Content Security Policy blocked no Botscent script. It reports other blocked resources as context only. |
script | A botscent.js script tag loads from the site's own origin. It is skipped when the page half is bundled. |
stack | The framework and the platform that the check recognises. |
adapters | The project imports botscent, and an existing proxy was wrapped, not replaced. |
Exit codes
| Code | Meaning |
|---|---|
0 | Installed. No check failed, and server-half or page-script passed. |
1 | Broken. At least one check failed. |
2 | Unverified. No check failed, and neither server-half nor page-script passed. |
64 | A usage error, such as a missing URL or an unknown option. |
Output for scripts and agents
With --json, the check prints one JSON object. This sample shows only the first of the 14 checks:
{
"check": "0.0.0",
"url": "https://botscent.nibnalin.me/",
"checks": [
{
"id": "reachable",
"outcome": "pass",
"observed": "200, text/html; charset=utf-8"
}
],
"exit": 0
}Each check has id, outcome and observed, and can have detail, cause and fix. The detail field holds the page's own text, such as its error messages.
With --report, the check adds a block to paste into an issue. The block has the versions, the stack, the adapters, the Botscent entries and the diagnostics. It has no query string, cookie, address or detail text.
The option names, the JSON field names, the check ids, the outcomes and the exit codes stay the same across minor versions. The text of each line can change in any release.
Common fixes
| Line | Likely cause | Fix |
|---|---|---|
UNKNOWN server-half at an origin | The transport is off. This is the default for Express, Astro, Hono on Node.js, Django, FastAPI, Flask and self-hosted Next.js. | If the server half is installed, no fix is needed. Your code still gets the request's own verdict. See From the server to the page. |
FAIL page-script: no botscent on the page | The page half is not loaded, or a script error stopped it. | Import botscent/auto in the client entry, add <Botscent />, or add the script tag. |
FAIL page-script: never started | Code imported the botscent entry and did not call start. | Call start once in the browser, or import botscent/auto. |
SKIPPED page-script | The check found no Chrome or Chromium. | Install Chrome, or pass --chrome <path>. |
FAIL entry: 2 entries | Two adapters each add an entry, or a cache adds a stored one. | Keep one server adapter on the path. |
FAIL no-store | A later layer replaced the no-store that the adapter set. | Keep Cache-Control: no-store on responses that carry a botscent entry. |
FAIL person | A shared cache replays an agent's response, so people get an agent's entry. | Turn the transport off. Then run the adapter in front of the cache. |
UNKNOWN transport | The page is on http and not on localhost, so the browser hides Server-Timing. | Run the check against the https deployment. |
FAIL csp | The Content Security Policy does not allow botscent.js. | Allow the script's origin in script-src, or serve botscent.js from your own origin. |
FAIL adapters: replaced | An existing proxy or middleware was replaced, not wrapped. | Restore the old file, and wrap its function with withBotscent. |
FAIL probes | A script on the page broke a browser API that a probe reads. | Run the check with --report, and open an issue with the report. |
FAIL page-verdict | The webdriver probe did not find the flag. | Run the check with --report, and open an issue with the report. |
Warning: If
personfails, turn the transport off now. A cache serves an agent's entry to people, and their pages then report an agent.
Related
npx botscent check: the full reference for the command.- From the server to the page: what the
Server-Timingentry is, and when an adapter writes it. - Quickstart: install Botscent with one prompt, or pick your framework.
- Log verdicts for a week: the first step once the check passes.