Troubleshooting Guide | Form Forge - Build Forms with AI in Seconds
Download Log in

Troubleshooting Guide

User Guide

When something goes wrong, this guide helps you diagnose and fix the most common Form Forge issues step by step.

Tooltip Help Opens the Homepage Instead of the Article

Symptoms: Clicking the small ? help icon in Form Forge admin opens the Form Forge landing page or docs homepage instead of the specific article for that setting. Fix: Update Form Forge to the current build. Admin help links now route to exact User Guide or Developer Guide section URLs. If a cached admin page still has the old link, hard-refresh the page once.

Live Preview Does Not Match the Published Form

Symptoms: A field, label, submit button, or success message looks styled in the builder controls but the live preview or published page still shows the theme/default style. Solutions:
  1. Update to the current build. Live preview now renders inside an isolated frontend canvas, using the same server-rendered form markup and Form Forge default frontend stylesheet as the published page. It also loads the conversational stylesheet and preview-safe calculation/conditional logic runtime. WordPress admin and Forge builder input styles should no longer change preview controls.
  2. Select the exact element in Live preview. Click the label, input, description, submit button, success message, or empty preview area for the form container. For form-level elements, use the explicit Form, Submit, and Success target buttons in Element Style if the element is hard to click in the preview. For a field wrapper, click any field element and switch the Element Style inspector to Field wrapper.
  3. Use the built-in style controls first. Font size, colors, border radius, padding, and border controls are saved in the form JSON and rendered with high-specificity inline declarations so broad theme/admin CSS cannot override them.
  4. Account for site-level CSS. If your theme or custom CSS applies global styles to inputs, labels, buttons, or form elements, the final published page can still differ from the preview. In that case, check the live page with browser developer tools and either narrow the theme rule or add a more specific Form Forge rule.
  5. Keep custom CSS declaration-only. The custom CSS boxes accept declarations such as letter-spacing: 1px;, text-transform: uppercase;, padding-top: 20px;, or margin-bottom: 30px;. Selectors, braces, url(), imports, scripts, and unsupported properties are stripped. Supported Custom CSS declarations render after generated style controls, so they override the same supported property.
  6. Refresh the preview. The preview auto-refreshes on most changes, but the Refresh button forces a fresh server render through the same renderer used on the frontend.

Layout Fields Show Input Settings or Broken Heading Markup

Symptoms: Heading, HTML Block, Divider, or Page Break fields show irrelevant Placeholder, Required, Description, Validation, or Default Value controls in Field Settings. A Heading may also appear on the frontend as duplicated label text or a raw-looking HTML fragment instead of a normal heading. Fix: Update Form Forge. Current builds treat layout fields as display-only helpers: Heading exposes only Heading text and Heading level, HTML Block exposes HTML content, and Divider/Page Break show explanatory notes. The frontend renderer suppresses wrapper labels/descriptions for layout blocks and renders Heading as a valid h1h6 element.

Builder Inspector Is Hard to Reach on Narrow Screens

Symptoms: On tablet/mobile-width admin screens, you click a field but Field Settings is far below the builder canvas, so you lose the selected-field context while scrolling. Fix: Update Form Forge. Current builds scroll the right inspector into view after selecting a field on narrow viewports, while preserving the selected field, Element Style target, and Live preview state. The collapse toggles still keep their state when reopened.

Save Form Fails Silently on the Free Plan

Symptoms: You already have the maximum number of free forms, click Save Form on a new form, and the network response says Form limit reached. Upgrade to Pro for unlimited forms. but nothing visible appears in the builder. Fix: Update Form Forge. Current builds show failed save responses as an error toast and re-enable Save Form so the user can upgrade, delete an old form, or continue editing an existing form without guessing what happened.

Long Text Labels Create Horizontal Overflow

Symptoms: A very long unbroken label or instruction pasted into a normal Text field stretches the published form horizontally, especially on mobile. Fix: Update Form Forge. Current frontend styles wrap long labels, descriptions, and field content inside the form width. For real multi-sentence instructions, use an HTML Block or Textarea instead of a Text field label.

Safe Custom Submit Action Does Not Run

Symptoms: The form submits successfully, but the modal, banner, or custom page element does not open. Solutions:
  1. Use a supported class action. Supported examples are document.getElementById('modal').classList.add('is-active');, document.getElementById('modal').addClass('is-active');, and document.querySelector('#modal').classList.toggle('is-active');.
  2. Check the target exists on the page. The element must already be present in the page HTML when the form submits.
  3. Avoid arbitrary JavaScript. Form Forge intentionally blocks fetch, XMLHttpRequest, eval, assignments, external URLs, cookie/storage access, script tags, and HTML injection. Use theme code or a small site plugin for complex custom behavior, then let Form Forge toggle a class.
  4. Use redirect for full navigation. If the desired action is moving visitors to /thank-you, choose Redirect to URL instead of a custom action.

Forge Suite Deactivate on a Clone Affects Another Site

Symptoms: You cloned or restored a WordPress site, then clicked Forge Suite > Deactivate on the clone. Another site using the same license appeared to lose PRO or Connect state. Cause: Older builds trusted the Freemius install id stored in fs_accounts. A cloned database can carry the original site’s install id and URL, so even an install-scoped Freemius deactivation can target the original remote install. Fix: Update Form Forge to the latest build. Forge Suite now compares the stored Freemius site URL with the current WordPress site_url() / home_url() before any remote deactivation. If the state belongs to another site, it skips the remote Freemius call and only clears local license state for the current WordPress install. Reconnect the clone through Form Forge > License > Connect to Avakode when you want it to be licensed again.

Inline Validation Errors Don’t Appear Until After Submit

Symptoms: Visitors fill out a form with a too-short text field or a number out of range, click Submit, and only see the error after the AJAX round-trip — the browser doesn’t show the native tooltip immediately. Solutions:
  1. Update to v1.0.10 or later. Earlier versions rendered the form with novalidate and didn’t run a JS-side checkValidity() gate. v1.0.10 keeps novalidate (so AJAX still works) but blocks Submit / Next on the first invalid visible field and shows the native browser tooltip.
  2. Custom themes that disable client-side validation. If your theme’s JS overrides the Form Forge submit handler, the gate may be bypassed. Re-enable it by removing the override or by calling form.checkValidity() yourself before your AJAX call.

Number Field with step — Visitor Can Bypass via Custom JS

Symptoms: Your number field is configured with min=10, max=100, step=5 and the spinner refuses values like 12 or 13. But you notice (in submissions or via API) that some submissions slip in with off-step values like 12. Solutions:
  1. Update to v1.0.10 or later. Server-side step enforcement is new — earlier versions only checked min/max on the server, so a client that POSTed directly to admin-ajax.php could bypass step. The fix uses (value - min) % step == 0 (float-safe) so external callers are now blocked too.
  2. Confirm the field configuration. In Field Settings → Validation, verify step is set. A step of 0 or empty disables the constraint.

Form Analytics Page Shows 403 / “You don’t have sufficient permissions”

Symptoms: You navigate to /wp-admin/admin.php?page=formforge-analytics and get a permissions error. Solutions:
  1. Update to v1.0.10 or later. The Analytics submenu was added in v1.0.10. Before that, the URL didn’t resolve to a registered admin page.
  2. Check capabilities. The page requires manage_options (Administrator role). Editors and lower roles see no submenu.
  3. PRO required. Analytics is a PRO feature; non-PRO sites see an upgrade banner instead of KPI cards or table data.
  4. Impossible conversion rates are capped. If older/imported data has completed submissions but very few tracked view events, current builds cap the displayed conversion rate at 100% rather than showing 200%, 400%, or another impossible value.

AI Recommendation Opens the Editor but Not the Right Field

Symptoms: You run AI Analysis from Submissions or Analytics, click a recommendation such as “Make field optional” or “Simplify label”, and the form editor opens in a generic state. The target field is not highlighted and no recommendation is visible beside the field settings. Fix: Update Form Forge. Current builds include the recommendation target in the editor URL, match it to the saved field id, scroll and highlight the field card with a neutral AI suggestion marker, open Field Settings, and show an inline From AI Analysis note next to the controls. The panel separates View cached analysis from Run new analysis so reopening the last result does not spend credits. Editor-side apply buttons use short labels and confirm the concrete result, such as Changed required to optional, so the admin can see what was changed. If the recommendation is form-level and has no field id, the editor still opens but no field is selected automatically.

Form Not Displaying on the Page

Symptoms: You added the shortcode or Gutenberg block, but the form does not appear. The page shows nothing, the raw shortcode text, or a blank space. Solutions:
  1. Verify the shortcode ID. Go to Form Forge > All Forms and compare the shortcode shown there (e.g.,

    Form not found.

    ) with what you pasted on the page. Even one wrong digit causes the form to not render.
  2. Confirm the form is saved. If you created the form but never clicked Save Form, it may not have a valid ID.
  3. Check for JavaScript errors. Open your browser’s developer console (F12 or Cmd+Option+I on Mac) and look for red error messages. A conflict with another plugin’s JavaScript can prevent forms from rendering.
  4. Clear your cache. If you use a caching plugin (WP Super Cache, W3 Total Cache, LiteSpeed Cache, WP Rocket), clear the cache after adding or updating the form.
  5. Switch to a default theme temporarily. Activate Twenty Twenty-Four or another default theme. If the form appears, your theme has a conflict. Contact the theme developer or add the form via shortcode in a different template area.
  6. Check for plugin conflicts. Deactivate all plugins except Form Forge, test the form, then reactivate plugins one by one to identify the conflict.

Submissions Not Saving

Symptoms: Visitors fill out and submit the form, but no submission appears in Form Forge > Submissions. The form may show a success message or may hang without responding. Solutions:
  1. Check the browser console for JavaScript errors. Errors from other plugins can prevent the form from completing its AJAX submission.
  2. Temporarily disable spam protection. Go to Form Forge > Settings > Anti-Spam and disable reCAPTCHA. If submissions start saving, the issue is your reCAPTCHA configuration (invalid keys or mismatched domain).
  3. Check server error logs. Ask your hosting provider for access to PHP error logs, or install a plugin like WP Debugging. Look for errors mentioning Form Forge or database write failures.
  4. Verify database permissions. Your WordPress database user needs INSERT permissions. This is rarely an issue on managed hosting but can occur on custom server setups.
  5. Test with all other plugins deactivated. If submissions work in isolation, reactivate plugins one at a time to find the conflict.

Email Notifications Not Sending

Symptoms: Submissions are saved in the dashboard, but you do not receive the notification email. Or the auto-reply is not reaching the submitter. Solutions:
  1. Install WP Mail SMTP. This is the fix in the vast majority of cases. WordPress’s built-in wp_mail() function is unreliable on most hosting providers. Configure WP Mail SMTP with Gmail, SendGrid, Mailgun, or your hosting provider’s SMTP server.
  2. Check your spam and junk folders. Emails from WordPress often trigger spam filters, especially if the “From” address does not match your domain.
  3. Verify notification settings. Open the form in the builder, go to the Notifications tab, and confirm the admin email address is correct and that Notify Admin is toggled on.
  4. Use the SMTP plugin’s test feature. Most SMTP plugins include a “Send Test Email” button. If the test email does not arrive, the problem is your email configuration, not Form Forge.
  5. Check hosting email limits. Some shared hosting plans limit the number of emails you can send per hour (often 50-100). If you have a high-traffic form, you may be hitting this limit.

Stripe Payment Failing

Symptoms: The visitor fills in their card details but sees an error when submitting, or the payment does not appear in your Stripe dashboard. Solutions:
  1. Verify you are not mixing test and live keys. Test keys start with pk_test_ and sk_test_. Live keys start with pk_live_ and sk_live_. Both the Publishable Key and Secret Key must be from the same mode.
  2. Check the Webhook Signing Secret. Go to Developers > Webhooks in your Stripe dashboard, click your endpoint, and compare the signing secret with what is entered in Form Forge. If in doubt, delete the webhook and create a new one.
  3. Inspect the browser console. Stripe.js logs detailed error messages. Common errors include invalid API key, incorrect element configuration, or network issues.
  4. Test with Stripe’s test card numbers. Use 4242 4242 4242 4242 for a successful payment and 4000 0000 0000 0002 for a simulated decline. Use any future expiry date and any 3-digit CVC.
  5. Confirm the webhook endpoint is reachable. In your Stripe dashboard under Webhooks, check for failed delivery attempts. If your hosting uses a firewall or WAF, it may be blocking Stripe’s webhook requests.
  6. Check that the payment amount is set. In the form builder, click the Payment field and verify the amount is configured (either a fixed value or linked to a Calculation field).
  7. Check the visible message. Declined cards should show the Stripe error only. If a decline also shows the form’s success message, update Form Forge and clear page/script cache.
  8. Check for stale Stripe JavaScript. Current builds cache-bust stripe-field.js with file mtime. If an optional Email field suddenly contains a pi_... PaymentIntent ID after payment, the page is running an older runtime; update Form Forge and clear any page/script cache.
  9. For Dynamic amount, verify the linked Calculation field. The amount display should update as the visitor changes source fields. If the calculated amount is below Stripe’s minimum, negative, missing, or mismatched against the submitted Calculation value, Form Forge blocks before creating a PaymentIntent.
  10. On Free plans, Payment is locked. The builder palette shows it as a PRO field, and a crafted save request is downgraded server-side instead of preserving a usable payment field.
“Could I be charged without my submission being saved?” No. Form Forge validates the whole submission server-side (anti-spam, reCAPTCHA, required fields) before the card is ever charged — a form that would fail validation never reaches the payment step. In the extremely unlikely event a charge succeeds but the submission still fails to persist (for example, a security token expiring in the split second between validation and save), the payment is recorded against the form with a captured_unsubmitted status so the site owner can see it and reconcile it — it is never silently lost. Payment errors in Conversational Mode. If a Stripe/card error happens while the visitor is on the final “submit” step of a conversational form, Form Forge navigates them back to the step that actually contains the Payment field and shows the error next to the Stripe Card Element. Field-level validation errors navigate to the step that owns the invalid field. Global errors such as reCAPTCHA, server, or network failures do not jump to an unrelated field; they stay on the current step and display as a general submit error. During validation, Stripe confirmation, and final submit, the visible conversational submit button is disabled and shows a loading label so the visitor cannot double-click without feedback. Stripe payment description. The Payment field’s Stripe payment description setting is sent to Stripe as the PaymentIntent description for reporting/accounting. It is not shown to the visitor. Use the regular field Description setting for helper text or payment copy displayed on the form. Payment placeholder. Stripe’s Card Element does not support the generic field Placeholder setting. Current builds hide that setting for Payment fields so admins do not expect placeholder text to appear inside the secure card iframe.

Map Not Loading

Symptoms: The Map Address field shows a blank area, a gray box, or an error message instead of an interactive map. Solutions:
  1. Verify your API key. Go to Form Forge > Settings > Maps and confirm the visible fields match the selected provider. Google mode shows only the Google Maps API key. Yandex mode shows the Yandex JavaScript, Geocoder, and optional Geosuggest keys. Google and Yandex JS keys are stored separately, so switching providers should not replace one with the other.
  2. Check API key restrictions. In the Google Cloud Console, verify that your API key has the Maps JavaScript API and Places API enabled. Overly restrictive referrer or IP restrictions can also block the map.
  3. For Yandex, keep the three services separate. The JavaScript API key renders the map, the Geocoder API key resolves typed addresses through WordPress, and the optional Geosuggest key enables live suggestions. Without the Geosuggest key, or when suggestions return 403, visitors can still type an address and press Enter or click Submit to resolve it through the Geocoder key. Validation waits for an explicit action, so the field should not show a map error while the visitor is only starting to type; clearing or blurring the input should close stale suggestions, and clearing the input should also clear coordinates and errors.
  4. Check the browser console. Google Maps errors are specific and tell you exactly what is wrong (e.g., “ApiNotActivatedMapError” means the Maps JavaScript API is not enabled, “RefererNotAllowedMapError” means your domain is not in the key’s allowed referrers).
  5. Verify billing is enabled. Google Maps requires a billing account linked to your project, even if you stay within the free tier.
  6. Test on a different page. If the map loads on one page but not another, the issue may be a CSS conflict or container sizing issue on that specific page.

File Upload Errors

Symptoms: Visitors see an error when trying to upload a file, the upload hangs, or the file does not appear in the submission. Solutions:
  1. Check the file type. The File Upload field only accepts file types you have allowed in the field settings. If a visitor tries to upload a .zip file but you only allowed .pdf and .docx, it is rejected.
  2. Check the file size. The maximum per-file size is 10MB. Additionally, your server may have lower PHP limits:
upload_max_filesize in php.ini (default is often 2MB)

post_max_size in php.ini (must be larger than the file size)

– Ask your hosting provider to increase these values if needed.

  1. Check the WordPress uploads directory permissions. The wp-content/uploads/ directory must be writable by the web server (usually permissions 755 or 775).
  2. Confirm the site still has PRO. File Upload is a PRO field. If a license expires or the site is downgraded to Free, existing saved forms keep their configuration in the builder, but the public form hides File Upload fields and the server rejects direct/tampered upload posts.
  3. Disable security plugins temporarily. Some security plugins (Wordfence, Sucuri, iThemes Security) block certain file uploads. Test with them deactivated.

reCAPTCHA Blocking Legitimate Submissions

Symptoms: Real visitors cannot submit the form. They see a spam-related error or the form silently fails, even though they are not bots. Solutions:
  1. Lower the score threshold. Go to Form Forge > Settings > Anti-Spam and reduce the reCAPTCHA threshold from 0.5 to 0.3 or 0.2. A lower threshold is more lenient toward visitors. Setting it to 0 disables score-based blocking. On local/dev domains such as localhost, 127.0.0.1, .local, or .test, threshold 0 also lets QA continue when Google rejects domain-mismatched test keys; on production domains Google verification must still succeed.
  2. Verify your reCAPTCHA keys match your domain. In the Google reCAPTCHA admin console, confirm that the domain listed matches your site exactly (including www vs. non-www).
  3. Check for VPN or corporate network issues. Some visitors on VPNs or behind strict corporate firewalls get low reCAPTCHA scores. If your audience commonly uses VPNs, consider a lower threshold.
  4. Temporarily disable reCAPTCHA to confirm. If submissions work without reCAPTCHA, the issue is confirmed. Adjust the threshold or rely on honeypot and time-check protection instead.

Conditional Logic Not Working

Symptoms: Fields that should show or hide based on another field’s value are always visible or always hidden, regardless of the visitor’s selection. Solutions:
  1. Confirm you have PRO active. Conditional logic is a PRO-only feature. Without an active PRO license, all conditional rules are ignored and every field is displayed.
  2. Check the trigger field name. The conditional rule references a specific field. If you renamed or deleted the trigger field, the rule breaks. Open the target field’s Conditional Logic tab and verify the trigger field is correct.
  3. Verify the condition value. The value in the rule must match the option exactly. If your dropdown has “Business” (capital B) but the rule checks for “business” (lowercase), it will not match.
  4. Test with a simple rule first. Create a basic test: a Radio field with “Yes” and “No” options, and a text field that shows when “Yes” is selected. If this works, the issue is with your specific rule configuration, not with the feature itself.
  5. Use the rule summary. The Field Settings panel now shows how many rules are configured for the selected field. Current builds stack each rule vertically in the right inspector so medium-width screens keep the source field, operator, value, and remove button readable. If you reorder cards while the settings panel is open, edits stay attached to the selected field ID rather than the card’s old position.
  6. Check for JavaScript conflicts. Conditional logic depends on JavaScript. Errors from other plugins can break it. Check the browser console.

Calculation Field Always Shows 0

Symptoms: You add a Calculation field, but the published form keeps showing 0 even after the visitor enters values in the source fields. Solutions:
  1. Add source fields first. Calculation formulas need existing field tokens. Add fields like Price and Quantity before configuring the Calculation field.
  2. Use the token chips. Open the Calculation field settings and click tokens such as {price} and {quantity} instead of typing them from memory. Tokens resolve by field ID or sanitized label, so “Unit Price” becomes {unit_price}.
  3. Check the formula. Use only numbers, tokens, +, -, , /, and parentheses. For example: {price} {quantity}.
  4. Set decimal places if needed. For currency, set Decimal places to 2, Prefix to $, and optional Suffix to the currency label.
  5. Test in Live preview. Current builds run the calculation runtime inside the builder preview. Field settings update the draft immediately, so type values into the preview inputs and confirm the result updates before publishing.
  6. Save the form. Click Save Form at the top so the updated draft is persisted.

Conversational Mode Issues

Symptoms: The form does not display in one-question-at-a-time mode, the animations are broken, or navigation between questions does not work. Solutions:
  1. Confirm PRO is active. Conversational mode requires PRO. Without it, the form displays in standard layout.
  2. Check the toggle. Open the form, go to Advanced settings, and verify Conversational Mode is toggled on.
  3. Avoid combining with multi-step. Conversational mode and multi-step mode serve similar purposes but work differently. Enable only one at a time.
  4. Check for CSS conflicts. Conversational mode uses full-width styling. Themes or page builders that constrain the form container width may cause layout issues. Try embedding the form in a full-width page template.
  5. Test on a clean page. Create a new page with only the form shortcode and no other content. If conversational mode works there, another element on the original page is causing the conflict.
  6. Update if conditional fields create blank steps or numbering gaps. Current builds remove conditionally hidden fields from the conversational step flow, renumber visible step badges, and recalculate progress. If Pickup/Delivery-style rules leave an empty question screen or jump from step 1 to step 3, update Form Forge and hard-refresh the page.

Analytics Responses Do Not Match the Submissions Page

Symptoms: The All Forms page or Analytics page shows more Responses than Form Forge > Submissions for the same form. Fix: Update Form Forge. Responses and Conversion Rate are now calculated from completed saved rows in wp_formforge_submissions, while view counts still come from wp_formforge_analytics. Rows with status = 'abandoned' are counted only in the Abandoned metric. A stale or diagnostic submit analytics event no longer inflates response counts.

Calendar Picker Availability Labels Look Squashed in the Field Settings Panel

Symptoms: When editing a Calendar Picker field in the form builder, the Availability fieldset in the right-hand Field Settings panel shows labels (Work start hour, Work end hour, Slot duration, Advance days) visually merging — text wraps onto two lines and runs into the next column’s label, the number input next to a label gets squeezed to ~50px wide. Cause (fixed 2026-04-26): Two compounding bugs. (1) A broader admin stylesheet rule forced every label inside .ff-admin .wrap to display: inline-flex with align-items: center, which placed label text and the number input on a shared row instead of stacking them; on narrow grid cells (~200px when the panel was below ~460px wide) the text wrapped and the input was visually merged into the neighbouring label. (2) Plugin admin enqueue versioned both admin.js and admin.css off the filemtime of admin.js only, so any CSS-only fix shipped with the unchanged ?ver= string and Hostinger / browser caches served the stale stylesheet — the v2 fix from earlier in the week never reached your browser. Fix: Update Form Forge to v1.0.7. Three changes shipped together:
  • The Field Settings labels are now forced to display: block with input below (the standard “label on top of input” pattern), regardless of the broader admin rule.
  • The inner Availability grid switches from a fixed two-column layout to repeat(auto-fit, minmax(220px, 1fr)), so it collapses to a single column when the panel is narrow and never squeezes inputs.
  • admin.css now versions on its own filemtime, so future CSS-only fixes always reach browsers immediately on deploy.

A hard refresh (Cmd+Shift+R / Ctrl+F5) on the form editor page may be needed once after the upgrade if your browser still has the old stylesheet open.

Calendar Picker Slot Times Look Wrong vs Google Calendar

Symptoms: A visitor in one timezone sees the slot at one clock time on the form, but after submission Google Calendar shows the event shifted by some number of hours. Or you (the admin) configured Work start hour = 3 in WP timezone UTC+3 and expected that to mean 00:00 UTC, but visitors saw something else. Cause (resolved 2026-05-21 — four rounds of fixes): Earlier builds mixed three clocks: WordPress site timezone, visitor browser timezone, and Google Calendar timezone. The durable flow is: field availability is interpreted in the WordPress site timezone, worker slots carry canonical UTC start values, the visitor-facing button label is rendered from that UTC instant in the visitor’s browser timezone, and the hidden submitted value remains UTC. The Submissions modal now formats calendar/date/time values through the same human-readable formatter used by email, CSV, PDF, Slack, Discord, and Telegram. How it works now:
  1. Admin sets Work start hour = 3 interpreted in the WP site timezone (Settings → General → Timezone). Admin in Europe/Moscow (UTC+3) → 03:00 Moscow = 00:00 UTC stored.
  2. Worker returns each slot with start = canonical UTC ISO (e.g. 2026-05-07T00:00:00.000Z).
  3. Frontend (visitor’s browser) filters availability by the field’s site-timezone wall clock, then renders the slot label via new Date(slot.start).toLocaleTimeString() — a UTC+5 visitor sees “05:00 AM”, a UTC+7 visitor sees “07:00 AM”, a London-BST visitor sees “01:00 AM”. All looking at the same physical moment.
  4. Hidden form value is the canonical UTC ISO with Z suffix — never local-naive again.
  5. PHP parses the UTC ISO as a real UTC moment (no TZ guesswork) and sends to Google as dateTime: 2026-05-07T00:00:00Z without any timeZone field.
  6. Google Calendar stores the exact UTC instant. Each viewer sees it in their own calendar TZ — calendar in UTC+5 shows 05:00, calendar in UTC+7 shows 07:00 — same instant, different clock per viewer.
How to verify on a live site: open the form, pick a date, then in the browser console run document.querySelector('.formforge-slot-btn').dataset.value. The output should be a UTC ISO with Z (e.g. 2026-05-07T00:00:00.000Z), while the button text should match the browser-local time for that same instant. For the admin-side check, compare your WP site timezone (Settings → General) to the slot start: e.g. Moscow site with picker work_start=3 must produce a slot.start at 00:00Z. After submitting, open Form Forge > Submissions > View and confirm the calendar value is readable date/time text, not a raw 2026-...Z string. If you still see drift after the v1.0.9 update: hard-reload the form once (Cmd+Shift+R / Ctrl+F5). The frontend calendar-field.js is cache-busted by mtime, but a tab that was already open before the update can still hold the stale script. Also confirm WP Settings → General → Timezone is set to a real city (e.g. Europe/Moscow) rather than a UTC offset — both work, but timezone strings handle DST automatically while offsets don’t.

Mailchimp Not Subscribing Contacts

Symptoms: Form submissions are saved, but new subscribers do not appear in your Mailchimp audience. Solutions:
  1. Check the connection status. Go to Form Forge > Settings > Mailchimp. If it shows “Disconnected,” click Connect and re-enter your API key.
  2. Verify the email field mapping. Open the form’s Integrations tab and confirm the correct form field is mapped to the Mailchimp email field. The dropdown lists only fields whose type is Email; if it is empty, add an Email field first.
  3. Check the audience selection. Confirm you selected the correct audience (list) in the form’s integration settings.
  4. Look for existing subscribers. Mailchimp does not create duplicates. If the email already exists in your audience, the contact is updated instead of appearing as a new subscriber. Check the audience’s recent activity for updates.
  5. Regenerate the API key. In Mailchimp, go to Account > Extras > API Keys, delete the old key, create a new one, and reconnect in Form Forge.
  6. Check support diagnostics. Current builds log Mailchimp skipped states and Worker errors to the formforge_integration_log option so support can tell whether the form lacked a valid email, audience, license token, or remote API success. A saved submission with status=error, message=Invalid request, and HTTP 400 means the request was rejected before Mailchimp received it; update to the current Worker build, which accepts empty merge-field maps and computes the required subscriber hash without relying on unsupported Web Crypto MD5.

Calendar Picker Availability Now Lives on the Field, Not the Google Card

What changed (2026-04-25, tightened 2026-05-20): Working hours, slot duration, advance days and day-of-week filter for the Calendar Picker field are configured on the field itself (Edit field > Availability), not on the form’s Google Calendar integration card. The picker is now usable as a standalone scheduling field — it renders slots based on its own rules even without a Google Calendar connection. With Google connected, the form-level card adds the calendar target and event title template. Busy slot filtering uses the worker’s FreeBusy API, then Form Forge filters the returned slots again against the field’s available days and work start/end hours. The same availability rules are rechecked on submit. Existing forms migrate transparently: if a field has no availability keys (older form), the renderer falls back to the form-level calendar_work_start / calendar_work_end / calendar_slot_duration we used to read. Re-open the form, edit the calendar field, save once to migrate the values onto the field.

Visitor Sees a Calendar Slot as Available After Google Already Booked It

Symptoms: A visitor books a slot via the calendar picker; the event lands in Google Calendar correctly. A second visitor opens the form on the same day and sees the same slot still selectable. They submit, the pre-submit FreeBusy check blocks the duplicate event, but the visitor sees a generic success message and walks away expecting a confirmation. Cause (fixed 2026-04-25): The worker generated candidate slot start times in its ambient UTC, but events created via FormForge were stored at calendar-local wall clock. A 17:00 slot was 17:00Z; an event submitted at 17:00 BST sat at 16:00Z in the FreeBusy response. The overlap check (slotStart bpStart) returned false and the slot reappeared as available. Fix: Update Form Forge to the latest version. The freebusy worker call now accepts the form’s timezone and interprets work hours in that zone via Intl.DateTimeFormat (DST-aware). The pre-submit FreeBusy check from earlier this week remains as defense-in-depth.

Visitor in a Different Timezone Sees Slot Labels Shift by Their UTC Offset

Symptoms: A form configured with working hours in the WordPress site timezone shows the expected available window, but a visitor in another timezone sees slot labels shifted from the admin’s wall clock. Cause (fixed 2026-05-21): This is now intentional for the visible label, not a booking error. Availability is still generated and filtered in the WordPress site timezone, but the visitor-facing label is projected into the visitor’s browser timezone so the user books the real instant they will see locally. Fix: Update Form Forge to the latest version. Slot buttons display browser-local labels from slot.start, but submit the UTC ISO instant. Admin submissions, notifications, exports, and PDFs format the stored value for humans instead of exposing raw UTC strings.

Google Sheets Rows Land in the Wrong Columns (Not Starting at A)

Symptoms: Submissions reach the spreadsheet, but new rows aren’t aligned to column A. The first row writes A..G, the next row jumps to start at column K, and so on — the table looks broken and any downstream import or formula that expects “Name in column A, Email in column B” fails. Cause (fixed 2026-04-26 — v1.0.8 + worker 37ca9a1a): The Sheets API’s :append endpoint takes a range parameter that tells Google where to look for the “logical table” to extend. We passed Sheet1!A:Z which makes Google scan all 26 columns for tables. Any stray cell outside the contiguous block at column A — a manual paste, leftover from an earlier test, an accidental header in column K — gets treated as its own table, and the next append lands at the right edge of THAT table. v1.0.8 anchors the range at Sheet1!A1, which is the canonical pattern in Google’s own docs: Google extends the A-column table downward and every new row starts strictly in column A regardless of stray cells elsewhere. Fix: Update Form Forge to v1.0.8 (worker version 37ca9a1a deploys atomically). The fix only applies to NEW submissions — already-misaligned rows in the sheet stay where they are. To clean up: delete the misaligned rows manually from the sheet; new submissions will land at column A. No re-export needed.

Submission Saves but Google Sheets Row Never Appears

Symptoms: Form submissions are saved in Form Forge → Submissions, the visitor sees the success message, but the chosen Google Sheet stays empty. No error in the browser console, no log entry. Cause (fixed 2026-04-25): The form’s Google Sheets integration required two things to be set: a spreadsheet picked via the picker AND the “Append submission row” checkbox ticked. Editors who used the picker but didn’t notice the separate checkbox shipped silent forms — fire_google_sheets() had a strict if (empty($settings['gsheets_enabled'])) guard that returned with no log entry, so it looked like everything worked end-to-end while the worker call never fired. Fix: Update Form Forge to the latest version. A configured spreadsheet ID is now sufficient on its own — fire_google_sheets proceeds whenever gsheets_spreadsheet_id is present, regardless of the checkbox. To pause the integration without losing the picker selection, clear the spreadsheet picker. Same logic now applies to Calendar (calendar_id alone enables event creation). Plus the form editor auto-ticks the enabled checkbox the moment the picker writes a value, and the Save handler also forces enabled=true if a value is set — three layers so the silent landmine doesn’t reappear.

Sheet Append Silently Returns 400 “Invalid request” — Submission Saves but Row Doesn’t Land

Symptoms: A form is configured with Google Sheets enabled, a spreadsheet picked, the visible sheet name matches reality. Visitors submit the form, success message appears, the submission shows up in Form Forge → Submissions, but the chosen Google Sheet stays empty. No error in browser console. No notification. Cause (fixed 2026-04-25, fourth iteration): Worker schema for /integrations/sheets/append requires values: z.array(z.string()). The PHP-side row builder included $submission_id (an int) and could include checkbox boolean values, both of which Zod rejected with 400 “Invalid request”. fire_google_sheets() silently swallowed the resulting WP_Error, so neither the user nor the admin saw any sign of failure. A diagnostic wp_option('formforge_gsheets_log') (last 50 calls) is now persisted by the integration so the next failure mode is easy to spot without redeploying a logging build. Fix: Update Form Forge to the latest version. Every value sent to the worker is now cast to a string before append (submission ID → string, booleans → ‘1’/”, arrays → comma-joined strval‘s). No more silent Zod 400s.

Calendar Slot Times Don’t Update After Plugin Update — Browser Cache

Symptoms: A Form Forge update was deployed (e.g. the timezone fix from this batch), but the form’s calendar picker on the frontend still behaves as if running the previous version — slot labels show the old shifted times, double-TZ behaviour persists. Cause (fixed 2026-04-25): Frontend assets calendar-field.js and frontend.js were enqueued with FORMFORGE_VERSION (a release-tag constant). Until the next major release the URL never changed, so visitors’ browsers reused the cached JS file even after a hot-fix deploy. Fix: Update Form Forge to the latest version. Both frontend scripts now append filemtime() to the version string, the same pattern admin.js already used. Each deploy rotates the asset URL automatically. No editor action needed; visitors who keep an open tab from before the fix can hard-reload (Cmd/Ctrl+Shift+R).

Sheet Append Returns “Unable to parse range” Even Though a Spreadsheet Is Selected

Symptoms: Form is configured with a Google spreadsheet picked via the picker, the integration is enabled, but submissions don’t reach the sheet. Worker logs show Unable to parse range: Sheet1!A:Z. Cause (fixed 2026-04-25): The Google Picker callback hard-coded Sheet1 as the tab name. If the spreadsheet’s first tab was renamed (e.g. Заявки, Submissions, Sheet 1 with a space, Лист1 for Russian-locale Google accounts), the configured gsheets_sheet_name no longer existed and Google rejected the append range. Fix: Update Form Forge to the latest version. The picker now resolves the actual first tab name asynchronously via Google’s Sheets API after a spreadsheet is selected. As a safety net, the worker’s appendRow also retries with the spreadsheet’s real first tab when it sees the “parse range” error. Either layer keeps existing forms working without a manual config change.

Submissions List Has No Pagination

Symptoms: Form Forge → Submissions shows every submission in one long table — once a form has more than ~20 submissions the page becomes hard to scroll and slow to scan. Fix (2026-04-25): Update Form Forge. The submissions page now paginates: choose 10 / 20 / 50 / 100 per page from a dropdown next to the form selector, and standard prev/next + numbered page links appear under the table. The page header also shows the total count and current page. SQL was changed from a hard-coded LIMIT 200 to proper LIMIT/OFFSET, so very large forms no longer load every row in one query.

Print / PDF Button on the Submissions Toolbar

History: Early builds of the Submissions screen had a top-level Print / PDF button that called window.print() and captured the entire WordPress admin page (sidebar, filters, pagination, footer). A later build wired it to the clean PDF endpoint but silently exported only the newest visible row, which was confusing; a build after that removed the button entirely. Current behaviour (2026-05-14): The top-level Print / PDF button is back on the Submissions toolbar next to Export CSV, and it now does a proper bulk PDF export. It generates one clean PDF document containing every submission that matches the current form selection and filters — the same scope as Export CSV — with each submission on its own page and a Form Forge header. No WordPress admin chrome appears in the output, and window.print() is not used. The export is capped at 500 submissions per run; over that, a notice asks you to narrow the filter or use CSV. The per-row PDF action in the actions column is unchanged and still exports a single submission. If you need PDFs for many submissions at once: click the row-level PDF action on each submission you need, or export to CSV and reserve PDFs for the specific records you want as standalone documents.

Form Settings Don’t Persist — Save Reverts to Defaults

Symptoms: You configure values in any of the form’s settings cards (Email Notifications, Slack, Discord, Mailchimp, Google Sheets, Google Calendar, HubSpot, Post Submission), click Save Form, and the next page load shows the old defaults. Downstream features that depend on those settings (e.g. Calendar booking using configured working hours, Sheets append using your spreadsheet ID, HubSpot sending leads) behave as if nothing was configured. Cause (fixed 2026-04-25): Each settings card emitted an inline IIFE that tried to attach a click handler to the Save Form button so it could merge its own keys into the hidden settings JSON before the main save AJAX fired. Those scripts ran during HTML parse, but the Save Form button was rendered later in the page — document.getElementById('formforge-save') returned null, the guard short-circuited, the listener never attached, and every card’s keys were silently dropped. Fix: Update Form Forge to the latest version. Each card’s save-attach block is now wrapped in jQuery(function(){…}) so the lookup runs after the DOM is fully parsed and the Save button exists. All eight cards persist their settings on save now. Existing forms that had keys missing from previous saves can be re-saved once to populate them.

Redirect or Safe Page Action Does Not Run After Submit

Symptoms: The form saves the submission and shows the success message, but a configured redirect never happens, or a safe action such as document.getElementById('modal').classList.add('is-active'); does not add the class. Fix: Update Form Forge to the latest version, then re-save the form. Redirect actions now navigate immediately after a successful AJAX response when the URL is root-relative or same-site. Safe page actions are still server-parsed into a structured allowlist; only class add/remove/toggle actions by ID or simple selector are allowed, and arbitrary JavaScript/network calls remain blocked.

Range and Color Fields Look Wrong on the Frontend

Symptoms: A Range field always renders as a generic 0 to 100 slider, or the Color field appears as a thin line instead of a usable picker. Fix: Update Form Forge to the latest version. Range Field Settings now expose Min value, Max value, Step, and Default value, and the frontend renderer uses those saved values. Color fields render as a compact swatch-style native color picker with a visible selected color.

Calendar Booking Shows Wrong Slots or the Event Lands at a Different Time Than Picked

Symptoms: You configure the form’s Google Calendar card with working hours 10:00-12:00 and Slot 60 min, but the frontend date picker shows slots far outside that range (e.g. 16:00-23:30). When a visitor does book a slot, the event in Google Calendar appears at a different time — typically shifted by the calendar owner’s UTC offset (e.g. a 10:00 pick becomes 17:00 on a UTC+7 calendar). Event duration is always 30 min regardless of the Slot setting, and the event title keeps an old template or leaves {email} literal. Cause (fixed 2026-04-24): The calendar picker field on the form editor and the form’s Google Calendar integration card stored similar-looking values under different keys (field.slot_duration vs form.settings.calendar_slot_duration, etc.). The renderer and the availability AJAX read the field keys; the event-creation path read the form keys. Since the integration card was the only UI most editors actually used, the field keys stayed at defaults (30 / 9 / 17), and the two sides drifted. Separately, event start/end strings were parsed via strtotime() in the PHP server’s timezone (UTC on Hostinger) and emitted as Z, so Google applied the calendar owner’s UTC offset on display. Fix: Update Form Forge to the latest version. The form’s Google Calendar settings are now the single source of truth — the calendar picker, the slot-availability AJAX, and the event creation all read from the same calendar_work_start, calendar_work_end, calendar_slot_duration, calendar_event_title, and calendar_timezone keys on the form. Event start/end are built in the form’s timezone and passed to Google with a timeZone field, so the event lands at the exact clock time the visitor picked, on any calendar. A pre-submit FreeBusy check also blocks double-bookings if two visitors race for the same slot.

Google Sheets Row or Calendar Event Arrives 1-2 Minutes Late During a Submission Burst

Symptoms: During a marketing campaign, viral post, or other legitimate spike, form submissions come in fast — users see the success message instantly, but the matching Google Sheet row or Calendar event shows up 1-2 minutes later. No submissions are lost, they just arrive on a delay. Why it happens (by design, 2026-04-24): Google enforces a 60 requests/minute/user quota on both Sheets and Calendar APIs. A single Google OAuth token is shared by every form on your site, so a sustained burst past that threshold would get 429’d by Google. To prevent dropped submissions, the Forge API worker caps the load at 50/min for Sheets and 30/min for Calendar (below Google’s own limit). When the cap is hit, the worker returns 429 with a Retry-After hint, and Form Forge re-schedules the call via WordPress cron. Up to three retries per submission; after that the worker has had enough time to bleed off and the remaining calls go through at normal speed. What to do: Nothing — this is the expected behaviour during a genuine burst. Submissions are saved to Form Forge’s own table immediately, so you never lose data. The delay is only in the propagation to Google. If you routinely see delays outside peak times, check for a webhook loop or a scheduled script re-submitting the form.

Google Connection Stays in “Connect” State After OAuth

Symptoms: You click Connect Google Account in Form Forge > Settings > Google, complete Google’s consent screen (warning + scope selection), and return to the admin tab — but the card still shows Connect Google Account instead of flipping to Connected / Disconnect. Pressing F5 on the admin tab reveals that the connection actually succeeded. Cause (fixed 2026-04-24): The Connect button opened Google’s OAuth flow in a new tab. The admin card was rendered server-side once on page load and had no client-side listener to react when the Worker received the refresh token and persisted it. Browsers also strip window.opener across Google’s cross-origin redirect chain, so a plain postMessage callback wasn’t reliable. Fix: Update Form Forge to the latest version. The Connect card now starts three parallel watchdogs after you click Connect: (a) a postMessage listener for the callback page if the opener survives, (b) a polling loop that hits admin-ajax.php?action=formforge_google_status every 2 seconds for up to 3 minutes, and (c) a visibilitychange listener that triggers one immediate status check when the admin tab regains focus. Any of the three detecting connected: true reloads the page exactly once, after which the card shows the Disconnect button and connected account state. No manual refresh needed.

Google, Mailchimp, HubSpot, or WhatsApp Connect Is Disabled Until You Connect Avakode

Symptoms: On Form Forge > Settings, the Google button is disabled or Mailchimp / HubSpot / WhatsApp shows a warning telling you to connect Form Forge to Avakode first. If a license key is present but the site-token binding is missing, secure integration cards show the same reconnect-to-Avakode warning instead of implying that PRO is inactive. Cause (fixed 2026-05-15): These integrations authenticate against the Forge API with both a license key and the site’s capability token. Older QA states could have a valid PRO license or a fresh Avakode reconnect token without the local site_token_refreshed_at marker, so the plugin immediately treated the token as stale and the Worker rejected Google, Mailchimp, or HubSpot requests. Other restored sites had the license only in Freemius state while formforge_license_data.key was empty. Another drift path was a connected Freemius install that existed in Freemius but no longer had the matching license_site:* binding in Worker KV, so /licenses/validate returned a valid plan without a site token. Fix: Update Form Forge to the latest version, then reconnect through Connect to Avakode once if the site was restored from a backup. Fresh site tokens are now trusted and stamped locally, the plugin can fall back to the Freemius license key when the local Form Forge license cache is incomplete, and the Worker can repair a missing KV binding by checking the current Freemius install for the same normalized site URL. Google, Mailchimp, HubSpot, and WhatsApp force-refresh the site token before their connect or submit requests. The Connect exchange also avoids slow Freemius install lookups when the Avakode site binding already proves the license state, so an upstream Freemius 520 should no longer surface as a WordPress cURL error 28 during reconnect. The integration cards still show a specific warning if no license or site token exists.

Settings Integration Actions Warn About Unsaved Changes

Symptoms: You change a global setting, then click an integration action such as HubSpot Connect, an integration Disconnect button, or a save-sensitive notification setting before saving. Older builds could reload or replace the card state and make the unsaved setting look lost. Fix: Update Form Forge. The Settings dirty bar is now fixed to the bottom of the viewport, and integration actions, including destructive disconnect submits, ask for confirmation before running while settings are dirty. Click Save Settings first when you want the new global values to persist.

WhatsApp Recipient Number Is Missing or Invalid

Symptoms: WhatsApp is enabled on a form, but no WhatsApp alert is sent after submission. Cause: The global WhatsApp card has no recipient number, the number was saved without a country code, or the site is missing its Avakode site capability token. Current builds no longer require the recipient to send /start; Form Forge saves only digits plus one optional leading +, then sends the normalized recipient phone plus the signed site token directly to the Forge API. Fix: Open Form Forge > Settings > WhatsApp, keep Enable WhatsApp integration globally on, enter the recipient in international format such as +998901234567, and save. Letters, spaces, dashes, and extra plus signs are removed at input/save time. If the log mentions a missing site capability token, reconnect Form Forge to Avakode from the License screen and retry.

Legacy WhatsApp /start Registration Still Needs Diagnostics

Symptoms: A legacy build or a direct Worker QA run sends /start CODE to the Avakode WhatsApp number, but the bot does not reply or the phone map does not change. Cause (legacy path): The current Form Forge admin setup no longer uses /start, but the Forge API still supports it for backwards compatibility. If no register_* rows appear in whatsapp_message_events, Meta probably did not deliver the inbound webhook to the Worker. Fix: Update the Forge API Worker. Current builds accept Meta verification and inbound webhook payloads on both /notifications/whatsapp/webhook and the shorter /notifications/whatsapp callback URL. The webhook recognizes malformed /start attempts before token lookup, replies with a specific message for missing code, invalid format, expired code, or not-found/already-used code, and writes register_connected, register_expired, register_not_found, or register_invalid_format rows to whatsapp_message_events.

Stripe, reCAPTCHA, Calendar, or Map Validation Stops Before Payment

Symptoms: In a conversational payment form, clicking Submit returns the visitor to a previous field or shows a field-level error, and no Stripe charge appears. Why it happens (by design, 2026-05-15): Form Forge runs a validation preflight before Stripe capture. That preflight now includes a fresh reCAPTCHA token, Calendar Picker future-slot validation, and Map Address coordinate validation. A typed map address without selected coordinates, a stale/past calendar slot, or a reCAPTCHA failure blocks the charge and sends the visitor back to the relevant step. What to do: Fix the field error and submit again. For Yandex maps, verify the JavaScript API key can load the map and add a Yandex Geocoder API key for typed address lookup; add the separate Geosuggest API key only if you want live suggestions. Without Geosuggest, the visitor can press Enter or click Submit after typing the address, or click the map. If a visitor clears the field, Form Forge should clear the previous coordinates and formatted address instead of restoring an old suggestion. For calendar fields, pick a future available slot. For reCAPTCHA, verify the site/secret keys match the domain.

Google Sheets Not Receiving Data

Symptoms: Submissions are saved in Form Forge, but no new rows appear in your Google Spreadsheet. Solutions:
  1. Check the Google connection. Go to Form Forge > Settings > Google. If it shows “Disconnected,” click Connect to re-authorize.
  2. Verify the Spreadsheet ID. Open the form’s Integrations tab and compare the Spreadsheet ID with the one in your spreadsheet’s URL (the long string between /d/ and /edit).
  3. Verify the sheet name. The sheet name (tab name at the bottom of the spreadsheet) must match exactly, including capitalization. “Sheet1” is not the same as “sheet1.”
  4. Check that the spreadsheet is not deleted or moved to trash. Open the spreadsheet URL directly in your browser to confirm it exists and is accessible.
  5. Re-authorize the Google connection. Disconnect and reconnect in Form Forge > Settings > Google to refresh the OAuth token.

Webhook Not Firing

Symptoms: You configured a webhook URL, but the receiving service (Zapier, Make, your API) does not receive any data when the form is submitted. Solutions:
  1. Verify the webhook URL. Open the form’s Integrations tab and confirm the URL is entered correctly. A single typo in the URL causes failure.
  2. Confirm PRO is active. Webhooks require a PRO license. Without PRO, the webhook URL is ignored.
  3. Test with a webhook debugging tool. Use a service like webhook.site to get a temporary URL. Set this as your webhook, submit the form, and check if the data arrives. If it does, the issue is on the receiving service’s end.
  4. Check the latest delivery status. Current builds record recent webhook attempts in wp_options.formforge_webhook_log, including HTTP status or error message. This confirms whether WordPress reached the endpoint.
  5. Check for server-side firewalls. Some hosting providers block outgoing HTTP requests from WordPress. Ask your host if outgoing POST requests are allowed.
  6. Verify the receiving endpoint accepts POST with JSON. Form Forge sends data as Content-Type: application/json. Some services expect form-encoded data. Check the receiving service’s documentation.

Slack or Discord URL Is Rejected on Save

Symptoms: You paste a webhook URL into Settings > Slack or Settings > Discord, click Save Settings, and see an error saying the URL must start with https://hooks.slack.com/services/ or https://discord.com/api/webhooks/. Cause (fixed 2026-05-07): Older builds accepted any HTTPS URL and only discovered the mistake later when delivery silently no-op’d. Current builds validate the service-specific host and path before saving so a broken URL doesn’t persist in settings. Fix: Paste the exact Incoming Webhook URL from Slack or Discord. If you want to temporarily disable the integration, clear the field entirely and save.

Form Abandonment Not Tracking

Symptoms: You enabled abandonment tracking, but no abandoned submissions appear in the dashboard. Solutions:
  1. Confirm PRO is active. Abandonment tracking is a PRO feature.
  2. Verify the toggle. Open the form, go to Advanced settings, and confirm Abandonment Tracking is toggled on.
  3. Understand when abandonment is captured. The visitor must interact with at least one field before an abandoned submission is created. Current builds autosave after field interaction while the visitor is still on the page and also send a final beacon when the page is closed or hidden.
  4. Check your caching setup. Aggressive page caching can sometimes interfere with the JavaScript that tracks field interaction. Clear your cache and test.
  5. Check the capture mode. By default Form Forge stores metadata only, such as touched field names, not typed values. If you need partial values, enable value capture explicitly in the Abandonment Tracking card and review your privacy policy.
  6. Check for duplicate drafts. Current builds keep one abandoned row per browser form session and delete it after a successful submit. If you see multiple abandoned rows from one typing session, clear cached frontend JS and verify the database has the session_id column.

Calendar Picker Showing No Available Slots

Symptoms: The Calendar Picker field displays but shows no available time slots, or all dates are grayed out. Solutions:
  1. Check the Google connection. Go to Form Forge > Settings > Google and verify the status is “Connected.”
  2. Verify the Calendar ID. In the form-level Google Calendar integration card, confirm you selected the correct Google Calendar.
  3. Check working hours configuration. Open the field settings and verify that Working Hours are set. If no working hours are defined, no slots are generated.
  4. Check available days. If Saturday or Sunday are disabled, those dates intentionally show no slots. A work end of 17 means the last visible slot must start before 17:00.
  5. Verify your calendar is not fully booked. Open Google Calendar directly and check that the dates in question actually have free time during your defined working hours.
  6. Check the slot duration and buffer time. If your working hours are 9:00 AM to 10:00 AM and the slot duration is 60 minutes with a 15-minute buffer, only one slot fits. Increase working hours or reduce slot duration.
  7. Look ahead further. The calendar shows a limited date range. Scroll forward to see if slots become available on later dates.

Forge AI Assistant Online

Hi! I'm the Form Forge AI assistant. Ask me anything about the plugin — setup, features, troubleshooting, or development.

Just now
Powered by Forge AI · Browse docs