Quick triage: the widget does not appear
Work through these steps in order — each one rules out a whole class of causes.
- Step 1: Is the tag in the page HTML? Run the command below; no match means the tag is not installed on this page or an old cached copy of the page is served — add the tag and purge the page cache. (CMS plugins use their own loader, so
/w.jsdoes not appear there — check the plugin's status page instead.) - Step 2: Is the key enabled? Run the
widget-configcommand below.{"enabled":false}→ the key is unknown or replaced, the project is not active, indexing is not finished, or ownership/plugin connection is invalid. First compare the key in the tag with Settings → Embed code: a stale or deleted key is not flagged in the dashboard. If they differ, replace the whole tag with the current one. If they match, the dashboard (Overview) shows project, indexing and connection status — see AISX-W110. Do not change CSP or caching for this. - Step 3: Enabled, but nothing visible? If the command returns
"enabled":true, open the page with DevTools → Console and look for lines starting with[ai-search]. Each carries anAISX-…code — find it in Console messages. - Step 4: Console is silent? See Silent failures: a CSP that blocks the script, a plugin that did not output the loader, a CMS plugin in Inline mode on a page without its shortcode/block (expected — no floating button there), or page CSS covering the widget.
<script …/w.js …> tag.curl -s "https://YOUR-SITE.example" | grep -o '<script[^>]*/w\.js[^>]*>'"enabled":true.curl -s "https://achlaai.com/api/widget-config?key=YOUR_PUBLIC_KEY"Silent failures (no [ai-search] line in the console)
| Situation | How to recognise it | Fix |
|---|---|---|
| The script is blocked by the site's CSP | The console shows a Content-Security-Policy violation for w.js (browser message, not [ai-search]); the Network tab shows the request as blocked. | Allow https://achlaai.com in script-src and connect-src — see the install guide. |
| The tag is missing on this page or the HTML is cached | The grep command in Quick triage finds nothing. | Add the tag (<script src="https://achlaai.com/w.js" data-key="YOUR_PUBLIC_KEY" defer></script>) to the page template and purge the page/CDN cache. |
| CMS plugin with Inline placement: no floating button on other pages | Pages without the WordPress shortcode [achla_search] / “Achla AI Search” block, or without the Drupal “Achla AI Search” block, show no widget at all. This is expected: the plugins use one placement mode for the whole site and, in Inline, load the widget only where the shortcode/block is rendered. | Insert the shortcode or block on that page, or choose Bubble placement in the plugin settings. For a floating button everywhere plus an inline box on one page, use manual tags — see Mixed placement. |
| A CMS plugin did not output the widget | No widget, no console line. The plugins record placement/release problems as data-achla… attributes on <html>: run document.documentElement.getAttributeNames().filter(n => n.startsWith('data-achla')) in the console. | Open the plugin settings: check the connection, indexing status, the “show the widget” switch and the placement diagnostics; reconnect if the connection was revoked. |
| The widget is covered by page elements | document.querySelectorAll('.aisx-btn, .aisx-inline, .aisx-drop').length is above 0, but nothing is visible. | The floating button and panel use z-index: 2147483000; check for theme elements with a higher z-index or for CSS that hides the #ai-search container. |
Older widget builds printed the same messages without the AISX-… code (for example [ai-search] inline: no <div id="ai-search"> on this page, falling back to bubble). Match them by text against the signals below.
When do changes take effect?
- Dashboard settings (placement mode, attach selector, appearance) reach visitors on the next page load within about 30 seconds.
/api/widget-configis served withCache-Control: no-store; each server instance caches widget settings for 30 seconds and the project record for 5 seconds. The tag on your page does not change, so no page or CDN cache purge is needed. - The widget code (
/w.js) is served withCache-Control: public, max-age=3600, must-revalidate, so a new widget version can take up to an hour to reach a visitor's browser. - Changes to the tag itself (adding it,
data-mode,data-attach,data-position, the key) are changes to your page HTML and take effect when your site serves the new HTML.
Console messages (AISX-W1xx)
Every message the widget prints has the form [ai-search] <CODE> <message> — <link>, where the link points to the matching section below.
| Code | Signal | Meaning |
|---|---|---|
| AISX-W101 | AISX-W101 missing data-key | The script tag has no data-key |
| AISX-W102 | AISX-W102 attach: invalid selector, falling back to bubble | Attach selector is not valid CSS |
| AISX-W103 | AISX-W103 attach: no input matched the selector, falling back to bubble | Attach selector matched nothing on this page |
| AISX-W104 | AISX-W104 inline: no <div id="ai-search"> on this page, falling back to bubble | Inline mode, but the page has no #ai-search container |
| AISX-W105 | AISX-W105 inline: target is already used, falling back to bubble | The #ai-search container is already used by another copy of the widget |
| AISX-W106 | AISX-W106 attach: matched element is not a free text input, falling back to bubble | Attach selector matched an element that cannot be used |
| AISX-W110 | AISX-W110 widget is disabled for this key (unknown key, index not ready, or access revoked) — check your dashboard | The widget is disabled for this key |
| AISX-W111 | AISX-W111 could not load widget configuration (network, CSP or server error) | The widget configuration could not be loaded |
| AISX-W112 | AISX-W112 data-key has an invalid format | The data-key value is malformed |
| AISX-W120 | AISX-W120 search request failed: | A search request returned an error |
| AISX-W121 | AISX-W121 search request did not complete (network error or timeout) | A search request did not complete |
AISX-W101 — The script tag has no data-key
console.error.[ai-search] AISX-W101 missing data-key — <link to this section>Cause. The <script> that loads the widget has no data-key attribute (or it is empty). The widget cannot tell which site it belongs to, stops immediately and renders nothing.
Fix. Copy the embed code again from your dashboard (Settings → Embed code): it already contains data-key="pk_…". If you add the tag with JavaScript, set data-key on the element before you append it to the page.
AISX-W102 — Attach selector is not valid CSS
console.warn.[ai-search] AISX-W102 attach: invalid selector, falling back to bubble — <link to this section>Cause. Placement mode is attach, but the selector (from data-attach or from the dashboard) is not a valid CSS selector — document.querySelector() threw an error. The widget shows the floating button (bubble) instead.
Fix. Use a valid CSS selector for your site's search field, for example input[type="search"] or #search-input. Set it in the dashboard (Settings → Widget mode) or in data-attach in the tag, or switch placement back to bubble. Dashboard changes reach visitors on the next page load within about 30 seconds — no cache purge needed (When do changes take effect?). After saving, reload the page and run document.querySelector('<your selector>') in the browser console — it must return the search <input> (type text or search), and the console must no longer show AISX-W102.
AISX-W103 — Attach selector matched nothing on this page
console.warn.[ai-search] AISX-W103 attach: no input matched the selector, falling back to bubble — <link to this section>Cause. Placement mode is attach, but no selector is configured, or the selector matches no element on this page at the moment the widget mounts. The widget shows the floating button (bubble) instead.
Fix. 1. Test the selector before saving it: on the live page, run document.querySelector('<selector>') in the browser console — it must return the search <input> (type text or search) that exists when the page loads. Adjust the selector until it does. 2. Save it in the dashboard (Settings → Widget mode) or in data-attach on the tag — or switch to bubble. If the field exists only on some pages, the bubble on the other pages is expected. 3. Reload the page and run the same document.querySelector('<selector>') again: it must still return the input, and the console must no longer show AISX-W103. Dashboard changes reach visitors on the next page load within about 30 seconds — no cache purge needed (When do changes take effect?).
AISX-W104 — Inline mode, but the page has no #ai-search container
console.warn.[ai-search] AISX-W104 inline: no <div id="ai-search"> on this page, falling back to bubble — <link to this section>Cause. Placement mode is inline (set in the dashboard or with data-mode="inline"), but no element with id="ai-search" exists when the widget mounts. The widget shows the floating button (bubble) instead of the inline search box.
Fix. Add <div id="ai-search"></div> to the page HTML exactly where the search box should appear (WordPress plugin: the [achla_search] shortcode or the “Achla AI Search” block; Drupal module: place the “Achla AI Search” block). Or switch placement back to bubble in the dashboard. A container inserted later by client-side JavaScript is not picked up. Dashboard changes reach visitors on the next page load within about 30 seconds — no cache purge needed (When do changes take effect?). After the change, reload the page: the console must no longer show AISX-W104.
AISX-W105 — The #ai-search container is already used by another copy of the widget
console.warn.[ai-search] AISX-W105 inline: target is already used, falling back to bubble — <link to this section>Cause. The #ai-search element was already claimed by another instance of the widget — almost always because the widget script is included twice on the page. The second copy falls back to the floating button, so the page shows both.
Fix. Keep exactly one widget tag per page. In the browser console, document.querySelectorAll('script[src$="/w.js"], script[src*="/widget/releases/"]').length must be 1. Remove the extra copy (theme template, tag manager, or a plugin plus a manual tag).
AISX-W106 — Attach selector matched an element that cannot be used
console.warn.[ai-search] AISX-W106 attach: matched element is not a free text input, falling back to bubble — <link to this section>Cause. Placement mode is attach and the selector matched an element, but it is not an <input> of type text or search (for example a <form>, a wrapper <div>, a button or a <textarea>), or another copy of the widget has already attached to it. The widget shows the floating button (bubble) instead. Only the first element matched by the selector is checked.
Fix. Point the selector at the search <input> itself, e.g. form.search input[type="search"] instead of form.search. If the field is already taken, remove the duplicate widget tag (see AISX-W105). Dashboard changes reach visitors on the next page load within about 30 seconds — no cache purge needed (When do changes take effect?). After saving, reload the page and run document.querySelector('<your selector>') in the browser console — it must return the search <input> (type text or search), and the console must no longer show AISX-W106.
AISX-W110 — The widget is disabled for this key
console.warn.[ai-search] AISX-W110 widget is disabled for this key (unknown key, index not ready, or access revoked) — check your dashboard — <link to this section>Cause. /api/widget-config answered {"enabled":false}. Possible reasons: the key is unknown or was deleted/replaced, the project is not active, the search index is not ready yet, or site ownership / the CMS plugin connection is no longer valid. The public endpoint deliberately does not say which. The widget renders nothing.
Fix. 1. Compare the data-key in the page's tag with the key in Settings → Embed code. If they differ (the old key was deleted or replaced), replace the whole tag with the current one — a stale or deleted key is not flagged in the dashboard, where the project can look healthy. 2. If the keys match, open Overview: project status, index readiness and site connection are shown there. If you connected through the WordPress or Drupal plugin, check the connection status in the plugin settings and reconnect if needed. Do not change CSP or caching — the request itself succeeded. Re-check with the widget-config check in Quick triage: it must return "enabled":true.
AISX-W111 — The widget configuration could not be loaded
console.warn.[ai-search] AISX-W111 could not load widget configuration (network, CSP or server error) — <link to this section>Cause. Three attempts to GET /api/widget-config failed: network error or timeout (1.5 s per attempt), the request was blocked by the site's Content-Security-Policy (connect-src), the server kept answering HTTP 429/5xx, or the response was not valid JSON. Without a configuration the widget renders nothing (it never shows itself without an explicit "enabled":true).
Fix. Open DevTools → Network and find the widget-config request. Blocked by CSP → allow the widget origin in connect-src (see the install guide, “Content-Security-Policy”). 5xx/timeouts → retry in a few minutes. Check the endpoint directly with the widget-config check in Quick triage.
AISX-W112 — The data-key value is malformed
console.error.[ai-search] AISX-W112 data-key has an invalid format — <link to this section>Cause. /api/widget-config answered HTTP 400: the data-key value is not a plausible public key (allowed: letters, digits, _, ., -, at most 128 characters). Typical causes: a typo, a truncated key, extra spaces or quotes, or a placeholder such as pk_XXXX left in the snippet. The widget renders nothing.
Fix. Copy the exact key from Settings → Embed code in your dashboard (it starts with pk_) and replace the whole data-key value. Do not edit the key by hand.
AISX-W120 — A search request returned an error
console.warn.[ai-search] AISX-W120 search request failed: <error code> — <link to this section>Cause. The visitor asked a question and /api/search answered with an error. The console line continues with the server's error code, e.g. AISX-W120 search request failed: quota_exceeded; it ends with unknown when the response carried no recognisable code (for example an HTML error page from a proxy or CDN instead of JSON). The visitor sees a short message in the widget.
Fix. Look up the trailing code in the search API error table (AISX-A201…AISX-A214) — each entry explains the cause and the fix.
AISX-W121 — A search request did not complete
console.warn.[ai-search] AISX-W121 search request did not complete (network error or timeout) — <link to this section>Cause. The request to /api/search failed before any response arrived (network error, request blocked by the site's CSP connect-src, or no answer within 60 seconds). The visitor sees an error message in the widget.
Fix. Open DevTools → Network and repeat the question. Blocked by CSP → allow the widget origin in connect-src. Timeouts → retry; if they persist, contact support from your dashboard with the time of the request.
Search API errors (AISX-A2xx)
When a visitor's question fails, /api/search answers with a JSON body containing error (and a visitor-facing message). Find it in DevTools → Network → the search request → Response, or at the end of the console line AISX-W120.
| Code | Signal | Meaning |
|---|---|---|
| AISX-A201 | missing_key_or_query | Key or question is missing |
| AISX-A202 | bad_request | Malformed request |
| AISX-A203 | payload_too_large | Request body too large |
| AISX-A204 | query_too_long | Question too long |
| AISX-A205 | invalid_key | Unknown or inactive key |
| AISX-A206 | origin_not_allowed | The widget is used on a site the key is not registered for |
| AISX-A207 | project_inactive | Project is not active |
| AISX-A208 | not_ready | Search index is not ready |
| AISX-A209 | project_payment_overdue | Subscription payment is overdue |
| AISX-A210 | rate_limited | Too many requests |
| AISX-A211 | daily_cap_exceeded | Daily safety cap reached |
| AISX-A212 | quota_exceeded | Search quota used up |
| AISX-A213 | quota_unavailable | Quota check temporarily unavailable |
| AISX-A214 | answer_failed | The answer could not be generated |
AISX-A201 — Key or question is missing
| HTTP status | error in the JSON response | What the visitor sees |
|---|---|---|
| 400 | missing_key_or_query | That question couldn't be sent. Please try again. |
Cause. The JSON body has an empty or missing key or query. The widget always sends both, so this normally comes from a hand-written API call.
Fix. Send {"key":"pk_…","query":"…"} with Content-Type: application/json.
AISX-A202 — Malformed request
| HTTP status | error in the JSON response | What the visitor sees |
|---|---|---|
| 400 | bad_request | That question couldn't be sent. Please try again. |
Cause. The request body is not valid JSON, or the question is empty after control characters and extra whitespace are removed.
Fix. Send a valid JSON body with a non-empty query. With the stock widget this is rare — retry the question.
AISX-A203 — Request body too large
| HTTP status | error in the JSON response | What the visitor sees |
|---|---|---|
| 413 | payload_too_large | Your question is too long. Please shorten it to 500 characters or fewer. |
Cause. The request body exceeds 16 KB, or the question exceeds 4096 characters.
Fix. Shorten the question (questions longer than 500 characters are rejected anyway, see AISX-A204).
AISX-A204 — Question too long
| HTTP status | error in the JSON response | What the visitor sees |
|---|---|---|
| 400 | query_too_long | Your question is too long. Please shorten it to 500 characters or fewer. |
Cause. After whitespace is collapsed, the question is longer than 500 characters.
Fix. Ask a shorter question (at most 500 characters).
AISX-A205 — Unknown or inactive key
| HTTP status | error in the JSON response | What the visitor sees |
|---|---|---|
| 401 | invalid_key | Search isn't available on this site. |
Cause. The key has an invalid format, does not exist, or has been deactivated (for example replaced by a new key).
Fix. Compare data-key on the page with Settings → Embed code in your dashboard; if they differ (the old key was deleted or replaced), replace the whole tag with the current one. A stale or deleted key is not flagged in the dashboard — the project can look healthy there. The same key makes /api/widget-config answer {"enabled":false} (AISX-W110).
AISX-A206 — The widget is used on a site the key is not registered for
| HTTP status | error in the JSON response | What the visitor sees |
|---|---|---|
| 403 | origin_not_allowed | Search isn't available on this site. |
Cause. The key is bound to the site registered for its project, and the request's Origin is not one of its origins. Allowed: the registered host over http or https, plus its www. / bare-domain counterpart. Other domains, staging subdomains and non-default ports are rejected.
Fix. Use the widget on the registered site. For another domain, register that site separately in the dashboard (each site has its own key), or contact support.
AISX-A207 — Project is not active
| HTTP status | error in the JSON response | What the visitor sees |
|---|---|---|
| 403 | project_inactive | Search isn't available on this site. |
Cause. The project behind the key is not active (suspended, being deleted, or blocked by billing), or its site ownership / CMS plugin connection is no longer valid (for example the plugin was disconnected).
Fix. Check Overview and Billing in your dashboard. If the site uses the WordPress or Drupal plugin, open the plugin settings and reconnect.
AISX-A208 — Search index is not ready
| HTTP status | error in the JSON response | What the visitor sees |
|---|---|---|
| 409 | not_ready | Search is still being set up on this site. Please check back a little later. |
Cause. The site's search index is not ready yet — the first indexing is still running or has not finished successfully.
Fix. Wait for indexing to finish; Overview in your dashboard shows the status. The widget does not render at all until the index is ready (AISX-W110).
AISX-A209 — Subscription payment is overdue
| HTTP status | error in the JSON response | What the visitor sees |
|---|---|---|
| 402 | project_payment_overdue | AI search is currently unavailable on this site. Please try again later. |
Cause. The subscription is past due or paused (or has ended) for longer than the grace period, so AI search is switched off before any paid processing.
Fix. Open Billing in your dashboard and settle the payment or update the payment method. Search resumes once the subscription is active.
AISX-A210 — Too many requests
| HTTP status | error in the JSON response | What the visitor sees |
|---|---|---|
| 429 | rate_limited | Search is busy right now. Please wait N seconds and try again. |
Cause. Too many questions in a short time — from one visitor IP address (20 per minute) or for the whole site (per-site limit per minute). The Retry-After header says how many seconds to wait.
Fix. Usually transient: wait and retry. If you are load-testing or a bot is hammering the widget, slow down.
AISX-A211 — Daily safety cap reached
| HTTP status | error in the JSON response | What the visitor sees |
|---|---|---|
| 429 | daily_cap_exceeded | Search is unavailable for the rest of today. Please try again tomorrow. |
Cause. The site reached its daily ceiling of AI searches — a protection against a copied public key being abused. It resets at the next midnight UTC (Retry-After gives the seconds).
Fix. Wait for the reset. If your genuine traffic exceeds the cap, contact support from your dashboard.
AISX-A212 — Search quota used up
| HTTP status | error in the JSON response | What the visitor sees |
|---|---|---|
| 402 | quota_exceeded | A list of the most relevant pages on the site instead of an AI answer; when no pages can be listed: “AI search is temporarily unavailable. Please try again later.” |
Cause. The plan's search allowance for the current billing period and any prepaid extra searches are used up (the Free plan stops at its monthly limit). AI answers pause until more searches are available.
Fix. In Billing: buy extra searches, enable auto top-up, or upgrade the plan — or wait until the allowance renews at the start of the next billing period.
AISX-A213 — Quota check temporarily unavailable
| HTTP status | error in the JSON response | What the visitor sees |
|---|---|---|
| 503 | quota_unavailable | Search is temporarily unavailable. Please try again in a moment. |
Cause. The quota service could not be reached for this request. Nothing was charged.
Fix. Retry in a moment. If it persists, contact support from your dashboard.
AISX-A214 — The answer could not be generated
| HTTP status | error in the JSON response | What the visitor sees |
|---|---|---|
| 502 | answer_failed | The answer couldn't be generated. Please try again. |
Cause. Generating the answer failed upstream. The search is not counted — it is returned to your quota.
Fix. Retry the question. If it keeps failing, contact support from your dashboard with the time of the request.
Install-check findings (AISX-C3xx)
Codes returned in findings[].code by the Achla AI installation check. The checker downloads one page as served (it does not run JavaScript) and compares it with the public widget configuration of the key it finds.
Run the check with GET https://achlaai.com/api/install-check?url=<page URL> (public, JSON, no key needed; results are cached for 60 seconds and rate-limited per IP), or with the Check installation button in the Achla AI dashboard (Overview and Settings, under the embed code). The response lists findings (code, severity, title, cause, fix, docs; AISX-C301 also carries detail — the concrete reason the page could not be fetched) and the limits of the check.
curl -s "https://achlaai.com/api/install-check?url=https://YOUR-SITE.example"| Code | Signal | Meaning |
|---|---|---|
| AISX-C301 | page_unreachable | The page could not be fetched |
| AISX-C302 | snippet_missing | No widget tag in the page HTML |
| AISX-C303 | snippet_duplicate | The widget tag appears more than once |
| AISX-C304 | key_missing | The widget tag has no usable data-key |
| AISX-C305 | widget_disabled | The widget is disabled for this key |
| AISX-C306 | inline_container_missing | Inline mode without an #ai-search container |
| AISX-C307 | attach_selector_no_match | The attach selector matches nothing in the page HTML |
| AISX-C308 | origin_mismatch | The key belongs to a different site |
| AISX-C309 | ok | Installation looks correct |
| AISX-C310 | foreign_script_host | The widget script is loaded from an unexpected host |
AISX-C301 — The page could not be fetched
Finding id: page_unreachable (severity: error).
Cause. The checker could not download the page: DNS or connection error, timeout, a non-2xx HTTP status, a non-public address, or a firewall/WAF that blocks automated requests. The detail field of the finding names the actual reason (for example HTTP 403, a timeout, or a non-HTML response).
Fix. Make sure the URL opens publicly without a login. If a WAF blocks it, the browser checks below still work; see also the crawler page (/en/bot).
AISX-C302 — No widget tag in the page HTML
Finding id: snippet_missing (severity: error).
Cause. Neither a widget <script> (/w.js) nor a CMS plugin loader was found in the HTML as served. The checker does not run JavaScript, so a tag added by a tag manager or by client-side code is invisible to it.
Fix. Add the embed code from your dashboard before </body>. If you insert it through a tag manager or JavaScript, verify in the browser instead: the console must show no [ai-search] errors and the widget must appear. Also purge any page cache after adding the tag.
AISX-C303 — The widget tag appears more than once
Finding id: snippet_duplicate (severity: warn).
Cause. The page includes the widget more than once. Each copy mounts its own widget (two buttons, or AISX-W105 for inline).
Fix. Keep exactly one tag per page — remove the copy from the theme, the tag manager, or the manual snippet if a plugin already adds it.
AISX-C304 — The widget tag has no usable data-key
Finding id: key_missing (severity: error).
Cause. The widget tag was found, but its data-key attribute is missing, empty, or malformed (AISX-W101, AISX-W112).
Fix. Copy the embed code again from Settings → Embed code in your dashboard.
AISX-C305 — The widget is disabled for this key
Finding id: widget_disabled (severity: error).
Cause. /api/widget-config returns {"enabled":false} for the key on the page: the key is unknown or was deleted/replaced, the project is not active, the index is not ready, or the site connection is no longer valid (AISX-W110).
Fix. First compare the key on the page with Settings → Embed code; if they differ (the old key was deleted or replaced), replace the whole tag with the current one. The dashboard shows project, indexing and connection status; a stale or deleted key is not flagged there. If the keys match, open Overview.
AISX-C306 — Inline mode without an #ai-search container
Finding id: inline_container_missing (severity: error).
Cause. The widget is set to inline, but the page HTML has no element with id="ai-search". Visitors get the floating button instead (AISX-W104).
Fix. Add <div id="ai-search"></div> where the search box should appear (WordPress: shortcode [achla_search] or the “Achla AI Search” block; Drupal: the “Achla AI Search” block), or switch placement to bubble.
AISX-C307 — The attach selector matches nothing in the page HTML
Finding id: attach_selector_no_match (severity: warn).
Cause. The widget is set to attach, but the selector does not match a text/search <input> in the HTML as served. Visitors get the floating button instead (AISX-W103, AISX-W106). A field rendered by JavaScript is invisible to the checker.
Fix. Correct the selector so that it targets the search <input>; verify in the browser console with document.querySelector('<selector>').
AISX-C308 — The key belongs to a different site
Finding id: origin_mismatch (severity: error).
Cause. The key on this page is registered for another site, so searches from this page are rejected with origin_not_allowed (AISX-A206).
Fix. Use the key of the project registered for this site, or register this site separately in the dashboard.
AISX-C309 — Installation looks correct
Finding id: ok (severity: info).
Cause. The tag is present once, the key is enabled, and the placement requirements are met in the page HTML.
Fix. Nothing to fix. Open the page in a browser and ask a test question to confirm an answer with sources.
AISX-C310 — The widget script is loaded from an unexpected host
Finding id: foreign_script_host (severity: warn).
Cause. The w.js tag points to a host other than the official widget origin — for example a self-hosted or CDN-cached copy. The widget derives its API address from its own script URL, so such a copy calls the wrong server and does not receive updates.
Fix. Load the script exactly as in the embed code from your dashboard; do not copy w.js to your own server or CDN.
Search does not know a page
- Plan page limit. Each plan indexes up to a fixed number of pages; pages beyond the limit are not indexed. Check the plan in Billing.
- robots.txt and firewalls. The Achla AI crawler respects
robots.txt. A WAF or bot protection that blocks it leaves pages unindexed — see the crawler page for how to identify and allow it. - JavaScript-only content. Pages whose text is rendered only in the browser may be indexed with little or no text.
- New or changed pages are picked up only when the site is re-crawled, not instantly.
Still stuck
Open Support in the Achla AI dashboard and include: the page URL, the exact [ai-search] console lines (with their AISX-… codes), and the output of the widget-config command above.