Symptom-first guide for the most common WordPress plugin issues. Every fix is grounded in the actual code path — no aspirational advice.
Check, in order:
Enabled toggle must be on.post + page are checked. WooCommerce product pages need an explicit opt-in.wp_footer()? The plugin injects the script via add_action('wp_footer', …, 99). A theme that omits wp_footer() from footer.php won't load the widget. Most modern themes call it; legacy custom themes occasionally don't.{base_url}/widget/widget.js should return 200. If you see connect-src violations in the console, your CSP needs an allowlist entry. See Allowed origins.| Error message | Diagnosis |
|---|---|
| "Connection failed." | Network-level — Pitchbar host unreachable from WP. Run wp shell, try wp_remote_get('https://app.pitchbar.example/up'). Common cause: outbound firewall blocking the Pitchbar host. |
| HTTP 401 invalid_token | Token plaintext is wrong (typo on paste) or the token was revoked in /settings/api-tokens. Reissue a new one. |
| HTTP 403 insufficient_ability | Token wasn't created with the wp:integration ability. Reissue with the right scope. |
| "Enter both a base URL and an API token, then try again." | One of the form fields is empty. The plugin defends client-side to avoid burning a request. |
| "Base URL must start with http:// or https://." | SettingsValidator rejects URLs without a scheme. Paste the full base URL with https://. |
| "API token format looks wrong" | Plugin expects pbar_ + 48 alphanumeric characters. Either the wrong string was pasted, or the token was truncated on copy. |
The sync POST returned successfully but the Pitchbar admin's Sources page shows no posts. Possibilities:
IndexDocumentJob on Horizon. On a busy worker this can run 30-60s behind. Check /admin/system → Failed jobs for any errors.skipped_unchanged count increments without re-indexing. The Document already exists; that's working as intended.
A resume transient (pitchbar_post_sync_resume or
pitchbar_product_sync_resume) sits in
wp_options but the WP-Cron continuation never
fires. Most likely:
wp-config.php for define('DISABLE_WP_CRON', true);. Some hosts disable it and run the cron via a real system cron — confirm with your host. If WP-Cron is fully disabled, manually run "Sync now" again from the Settings page; the syncer reads the resume marker on its first call and picks up where it stopped.wp cron event list on the command line. The pitchbar_run_full_sync_event / pitchbar_run_product_sync_event entries should appear with a next-run timestamp in the past. wp cron event run --due-now forces them.wp eval '(new \Pitchbar\Sync\PostSyncer)->runFullSync();'.If you want to start the next sync from page 1:
wp transient delete pitchbar_post_sync_resume
wp transient delete pitchbar_product_sync_resume
The next "Sync now" click then enumerates from page 1 again. Re-syncing is cheap — Pitchbar's content_hash short-circuit avoids re-embedding unchanged posts.
Three possibilities:
\Elementor\Plugin::$instance->frontend->get_builder_content_for_display, FLBuilder::render_content_by_id, and \Bricks\Frontend::render_content. A major version that renames these returns an empty string and the plugin falls through to the vanilla path. Confirm with: wp eval '$post = get_post(YOUR_ID); echo (new \Pitchbar\Sync\PageBuilderContent)->detectBuilder($post);'.pitchbar_post_content_html filter. If your code returns an empty string from the filter, no content is sent. Check functions.php / mu-plugins / any custom plugin.pitchbar_conv_id cookie. The widget writes it at init; check DevTools → Application → Cookies for the WP site origin. If absent, the widget probably never loaded on the chat page (see "Widget doesn't appear" above).woocommerce_load_cart_from_session hook calls WC()->cart->has_discount($code) first and skips if already applied. WooCommerce only allows one of each unique code; switching codes requires removing the previous one.new WC_Coupon($code)->get_id(). If the code no longer maps to a coupon, the apply call returns 400 invalid_coupon.cart-state.js isn't loaded. Open DevTools → Sources, search for pitchbar-cart-state. The script only enqueues when WooCommerce is detected AND the plugin is configured.localStorage.setItem. The script catches the exception silently — there's no error UI. The trigger requires localStorage; degrade gracefully by adding a different proactive rule (e.g. time or idle).added_to_cart event. The script's DOM-click fallback covers buttons with .add_to_cart_button / .single_add_to_cart_button classnames — if your theme uses different classnames, the cart state isn't recorded. Add an inline shim or open an issue.idle_minutes threshold isn't met. The widget polls every 30s and fires when now - timestamp > idle_minutes * 60_000 ms. A 5-minute threshold means at least 5 minutes of zero cart events must elapse before the trigger considers the cart abandoned. Double-check the rule's conditions.idle_minutes.
Pitchbar → plugin call returns 401 with
{ "error": { "code": "signature_mismatch" } }. The
plugin logs "Plugin REST HMAC mismatch" via
error_log when this happens. Causes, in order:
date -u. Compare to https://time.is. If skew > 5 minutes, NTP isn't running or is broken on the host. Fix at the OS level.shopper_signing_secret doesn't match Pitchbar's. This happens if you regenerated the API token in Pitchbar (which rolls a new shopper_signing_secret) without re-running "Test connection" in WP. Re-click Test connection — the plugin captures the new secret silently.plugin_unconfigured rather than signature_mismatch. Indicates the plugin was upgraded from a pre-1.1.0 install where the secret didn't exist yet. Re-click Test connection./wp-json/pitchbar/v1/* from rewrite/scan rules.
The plugin emits data-page-dir="rtl" and
data-page-locale on the widget script tag. The
widget reads them and mirrors the bar to the right edge of the
viewport on Arabic, Hebrew, Persian, and Urdu locales.
determine_locale() (which respects per-user overrides) and falls back to get_locale().Customize, your custom rules may not have RTL variants. Inspect .pitchbar-bar in DevTools — it should have dir="rtl" set when the page is RTL.
On v2.0.0+ this is impossible — the plugin defers to
woocommerce_loaded. If you're seeing this on an
older install, upgrade to v2.0.0. Symptoms of the v1.x bug:
woocommerce_inactive even though Woo runs fine in /shop.
The plugin writes to error_log via
Pitchbar\Support\Logger. To see them on a typical
WordPress install:
WP_DEBUG_LOG to true in wp-config.php.wp-content/debug.log prefixed with [pitchbar].If none of the above resolves your problem, open an issue with:
wp-plugin/pitchbar/pitchbar.php or in Plugins admin).wp-content/debug.log tail.