Skip to content
Botscent

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:

Terminal
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:

Terminal
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:

  1. 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.
  2. 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-Timing entries, console errors and Content Security Policy violations.
  3. It reads the project in the current directory, or in the directory that --project gives. It finds the frameworks and every botscent import. It compares a Next.js proxy or a Vercel middleware file with its version at git HEAD.

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

OptionWhat 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-browserSkips the checks that need a browser.
--jsonPrints the checks as JSON.
--reportAdds a block to paste into an issue.

Outcomes

OutcomeMeaning
passThe check observed what a working install gives.
failThe check observed a broken install. The line gives the likely cause and the fix.
unknownThe check cannot tell from outside whether the install is correct. The line gives the likely cause.
skippedThe check had nothing to test, for example because no browser was found.

The checks

The checks run and print in this order:

CheckWhat it tests
reachableThe page answers with a status below 400. A challenge page from the site's own protection gives unknown.
server-halfThe check's own request gets a botscent entry in Server-Timing, and the entry names botscent-check.
entryThere is one entry, and it was written between 10 s before and 120 s after the check's request.
no-storeThe response that carries the entry also has Cache-Control: no-store.
personThe request with an empty user agent gets no entry.
cacheIf people get cached HTML, the cached HTML carries no botscent entry.
page-scriptThe page half is on the page and has started.
page-verdictUnder automation, the page verdict is agent with the reason browser.webdriver-flag.
transportThe page received the entry from the server half.
probesNo probe of the page half failed. A probe that the browser does not support is a pass.
cspThe Content Security Policy blocked no Botscent script. It reports other blocked resources as context only.
scriptA botscent.js script tag loads from the site's own origin. It is skipped when the page half is bundled.
stackThe framework and the platform that the check recognises.
adaptersThe project imports botscent, and an existing proxy was wrapped, not replaced.

Exit codes

CodeMeaning
0Installed. No check failed, and server-half or page-script passed.
1Broken. At least one check failed.
2Unverified. No check failed, and neither server-half nor page-script passed.
64A 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:

Terminal
{
  "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

LineLikely causeFix
UNKNOWN server-half at an originThe 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 pageThe 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 startedCode imported the botscent entry and did not call start.Call start once in the browser, or import botscent/auto.
SKIPPED page-scriptThe check found no Chrome or Chromium.Install Chrome, or pass --chrome <path>.
FAIL entry: 2 entriesTwo adapters each add an entry, or a cache adds a stored one.Keep one server adapter on the path.
FAIL no-storeA later layer replaced the no-store that the adapter set.Keep Cache-Control: no-store on responses that carry a botscent entry.
FAIL personA 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 transportThe page is on http and not on localhost, so the browser hides Server-Timing.Run the check against the https deployment.
FAIL cspThe 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: replacedAn existing proxy or middleware was replaced, not wrapped.Restore the old file, and wrap its function with withBotscent.
FAIL probesA 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-verdictThe webdriver probe did not find the flag.Run the check with --report, and open an issue with the report.

Warning: If person fails, turn the transport off now. A cache serves an agent's entry to people, and their pages then report an agent.