Troubleshooting

Most common deployment and runtime issues and how to diagnose them.

Debug Mode and Console

Debug mode prints to the browser console (F12, Console tab) why rules behave the way they do. It is not just for designers: an administrator can see whether a script ran, whether a rule was skipped due to invalid fields, and what marked a field as "dirty".

Enabling Debug Mode

MethodScope
URL query parameter ?fcdebug=1 (also accepts true, yes, on)For this page load only. Nothing is saved.
In console: localStorage.setItem('fc.debug', '1') and reload the pagePersistent in this browser until you remove the key.
Form Settings, toggle "Debug mode for rules and scripts" (debugMode)For all form users, saved in the configuration. See Debug Mode.

Debug mode is evaluated when the form opens. When disabled, nothing is logged or allocated. Log entries are prefixed with [FC debug].

What Is Logged

Browser console with debug mode logs expanded: collapsed "[FC debug] rules …" group with condition and action tables and "dirtyFields changed" line

Render Counter

In debug mode, window.__fcRenderCounts is available: the render count of individual components (by field name). Type it into the console to check whether a single field is causing the whole form to re-render. In normal operation, it has zero overhead.

// after enabling debug mode and opening the form
console.table(window.__fcRenderCounts)

Form Does Not Appear

  1. Is the form active? Run Manage-FormCustomizer.ps1 -Action Status or open the "Custom form" dialog (if the form is already active, the command bar button is named "Open FormCraft 365 editor" and activation status is in the designer under "List Activation"). See Activation. Status "OTHER COMPONENT" means the list uses a different form.
  2. Is the package deployed and enabled? In the App Catalog, verify that the "Enabled" and "Deployed" columns are set and that tenant-wide deployment was selected.
  3. Upgrade did not take effect: after uploading a new version, hard-refresh the page (Ctrl+F5). The new version must have a higher version number (see Upgrading).
  4. Form opens with the default layout: the configuration failed to load. See Configuration Load States.
  5. Open the console and look for an error prefixed with [CustomFormCustomizer] or the message "Error initializing form".

Configuration Load States

When opening the form, configuration is read from the list's config.json and backup.json files and evaluated into one of four states.

StateMeaningBehavior
okValid configuration found (or migrated from an older schema version).Form runs according to the configuration.
notFoundFile does not exist (HTTP 404). No one has saved the form yet.Default layout from list columns is used. Saving works normally.
invalidFile exists, but contains broken JSON or does not match the schema (and no newer valid copy exists).Form runs with the default layout, nothing is overwritten, saving is blocked. Admin sees a "Fix configuration" banner (see Raw JSON).
unreadableReading failed for a reason other than 404 (403, 429, 5xx, network).Default layout, saving blocked ("Failed to read saved configuration"). Regular users see "The form could not be loaded completely. Please contact the site owner." Refresh the page and verify read permissions on the FormCustomizer folder (see Permissions).

The ok state can also carry a "newer version" flag; see below.

Invalid Configuration and the Raw JSON Panel

If the saved configuration is invalid, it is never silently overwritten with the default state. The form administrator receives a warning and a Fix configuration button, which opens the designer with the Saved configuration is invalid panel.

  1. In the panel, review Issues found (schema path and reason, or JSON syntax error).
  2. Edit the JSON in the Saved configuration (Raw JSON) field. Typically, you add a missing required property or fix a typo in a field type name.
  3. Click Validate and apply JSON. A valid configuration loads into the designer and saving is unlocked.
  4. Save your changes using the normal save button.
Designer over an invalid configuration: heading "Saved form configuration is invalid", list of issues found, Raw JSON field, and "Validate and apply JSON" button

Unknown keys from the saved JSON are preserved during repair. If you cannot fix the error, use a file from history or "Restore from backup" in the designer menu (the last valid backup backup.json).

Configuration History

Before every overwrite, the previous configuration is copied to SiteAssets/FormCustomizer/<listId>/history/ as <listId>.<timestamp>.json. The last 10 versions are kept. Writing history has a 5-second timeout and its failure does not block saving. On the first storage lock, pre-lock history is deleted (untrusted content).

The designer does not yet have a UI button to restore from history. Procedure:

  1. Open the Site Assets library, folder FormCustomizer/<listId>/history (you can find the list ID in the list settings URL or via Get-PnPList).
  2. Download the desired version and open it in a text editor.
  3. In the designer, open the Raw JSON panel, paste the contents, and click Apply JSON, or use configuration import.
  4. Save the form.

The most recent backup (one version) is also available in the designer menu as Restore from backup.

Configuration from a Newer Product Version

Every saved configuration carries a schemaVersion. If it is higher than the version supported by the package (for example, you uploaded an older .sppkg), the form renders on a "best-effort" basis, but saving is blocked to prevent data loss. The designer displays "Configuration comes from a newer product version" with the schema versions. Resolution: upgrade the package to the newer version (see Upgrading). Do not overwrite the configuration with an older version.

Configuration Does Not Save or Is Lost

HTTP 403 When Saving

The message "You do not have permission to perform this operation in SharePoint (HTTP 403)" means the user lacks write access to the configuration folder. Most common causes:

Storage Is Not Locked

The warning "Configuration storage is not locked: anyone with Manage Lists permission can overwrite it" is shown to a site owner after saving if locking failed or has not been set up. Resolution: save the form (or click Lock Now) as a site owner with Manage Permissions, or run the command from PowerShell. Message variants:

HTTP 400 Error on File Paths

The message "Specified value is not supported for the serverRelativePath parameter" (HTTP 400) means a web-relative path was sent to SharePoint. File and folder functions require a server-relative path (/sites/<site>/SiteAssets/…). The product constructs paths properly. You will mainly encounter this in custom scripts, queries, or manual code edits: use toServerRelativePath.

Save Conflict (412)

When saving an item, its ETag is checked: if another user modified it in the meantime, SharePoint returns HTTP 412 and the form shows the Item was modified elsewhere dialog with details on who changed it and when. The user chooses:

This is not a deployment bug. If you see unusually many conflicts, look for a workflow or automation modifying the item shortly after the form is opened. The message "The item was modified by another user in the meantime. Please refresh the page (HTTP 412)" appears for operations that do not offer the dialog. This behavior is described in Working with the Form. Form configuration does not report 412 conflicts (it saves based on savedAt, not ETag).

"Item was modified elsewhere" dialog showing who modified the item and when, with Reload, Overwrite anyway, and Cancel buttons

Unloaded Fields

Item values are loaded in batches ($select / $expand). If a batch fails (source list permissions, SharePoint error), the form still opens and displays fields from the failed batch as read-only with a banner "Fields failed to load and are read-only (will not be saved): …". On save, they are not written, preventing data from being overwritten with empty values. Resolution: reload the form, verify the user has read access to source lists (lookup, taxonomy, people).

Unindexed Column

On lists with more than 5,000 items, SharePoint rejects queries filtering on an unindexed column (list view threshold). Related Items and Related Documents widgets therefore do not run such a query and display "Column "…" is not indexed. On lists with more than 5,000 items, it must be indexed." Resolution:

Search in lookup fields over 500 items automatically switches to querying after typing at least two characters (showing the hint "Start typing to search…"), so indexing does not need to be handled there.

Scripts Are Not Working

  1. Are scripts enabled? The default state is disabled. Form administrators will see a banner "Custom scripts are disabled on this tenant…". To enable, see Script Policy. Changes take up to 15 minutes to take effect.
  2. In debug mode, look for script skipped: tenant policy disabled (policy) or script … ERROR (code error).
  3. A message about CSP / unsafe-eval means the environment prohibits dynamic execution; see CSP.
  4. When scripts are disabled, onBeforeSave does not run and saving is not blocked. Use rules with the blockSave action.

License Was Not Recognized

The designer shows Community Free even though you have a key:

  1. Open the License dialog and paste the key again. The dialog validates it and explains the reason (different tenant, different site collection, expired, invalid signature…). The error table is in Licensing.
  2. Verify the key is stored where it is read: tenant Storage Entity, or SiteAssets/FormCustomizer/license.txt in the root web of the site collection.
  3. A change made outside the designer (PowerShell, manual file) may take up to an hour to appear (raw key cache). It takes effect immediately after clearing _fc_lic_* keys in localStorage.
  4. A key for specific site collections does not apply to others. Send the vendor the Site Collection ID from the dialog.

"Custom form" Button Missing from List Command Bar

Work through these steps in order. The first steps reveal the most common causes:

  1. Check the … overflow menu at the right end of the command bar. If the bar is crowded, SharePoint moves custom commands there. The extension cannot control this.
  2. Microsoft Lists sync. Symptom: the first load after "Clear site data" shows the button, subsequent refreshes (F5) do not; other lists not handled by sync work fine. The cause is the local OneDrive sync client (Microsoft Nucleus), which serves list data locally via a service worker. Its response has "ShouldLoadSPFramework": false and custom actions without SPFx extensions, so SharePoint only preloads the extension package ("preloaded but not used") and the command set's onInit is never called. Our code cannot influence this; SPFx does not run at all. Verification: F12, Network tab, the RenderListDataAsStream request goes to localhost:42050 (or has header server: MicrosoftNucleus). Recommended permanent fix: in List Settings (Advanced settings, Offline Client Availability) choose No, or leave Disable offline availability of the list checked when activating the form (sets the ExcludeFromOfflineClient list property; the list will not be available offline). The designer warns about this on the List Actions tab. Tenant or device-level alternative: the DisableListSync policy. Other options: open the list in a way not served by Lists sync, or temporarily clear site data; permanently, the tenant or user can disable Microsoft Lists sync (check Microsoft documentation for options; verify Set-SPOTenant -DisableListSync in Microsoft documentation).
  3. In the Tenant Wide Extensions list, no Form Customizer component entry may have Disabled = Yes. SharePoint does not deliver disabled entries at all, so the corresponding command (e.g., FormActivatorCommandSet-100 for the command bar) will not run.
  4. Only users with the ManageWeb permission on the list (site owners, Full Control) see the button. The check result is cached in sessionStorage per tab, so open the list in a new tab, especially after permission changes.
  5. Try opening the list in an incognito/private window. If the button appears there, the regular window is holding stale site data (typically after fixing Tenant Wide Extensions entries): F12, Application tab, Storage, Clear site data, then Ctrl+F5.
  6. The command is available on lists with template 100, 120, and 1100. Document libraries (template 101) do not have the command.
  7. In the App Catalog, check the Tenant Wide Extensions list. It must contain 6 entries for templates 100, 120, and 1100: 3 command bar entries with Component Id 4a8b7c12-5d3e-4f9a-8b1c-6e2d9f4a3b5c and 3 context menu entries with Component Id a9998067-8e06-423f-b8a0-3177988f3a42 (since version 1.28.1). Delete old context menu entries (FormActivatorCommandSet-ContextMenu-*), as they create duplicate registrations. Add missing ones and delete obsolete ones; see Installation.
  8. Verify the package loaded. In the browser console (F12), run performance.getEntriesByType("resource").some(e => e.name.includes("form-activator")). true means the extension loaded. After navigating between lists in the app, the value may belong to a previous list, so check in a new tab with the list open.
  9. Changes take effect on sites within approximately 20 minutes. Afterwards, refresh the page with Ctrl+F5.
  10. Enable extension diagnostics. In the browser console (F12) on the list page, run localStorage.setItem("fc.debug","1") and refresh the page. Logs appear as console warnings (console.warn) prefixed with [FormCraft]. SharePoint clears the console during load, so enable Preserve log in DevTools console settings. Lines starting with [FormCraft] show which component is running (FormActivatorCommandSet = command bar, FormListActionsContextMenu = context menu), its registration properties, list ID and template, permission check inputs and resulting main command visibility, count of loaded list actions, visibility decisions for individual slots, and every command bar redraw. If no [FormCraft] line appears, the component did not start (see Microsoft Lists sync and registration check above). Disable diagnostics with localStorage.removeItem("fc.debug").

Console Noise

Some console messages are not errors:

You can recognize a real issue by a UI banner (red or yellow bar) or an error prefixed with [CustomFormCustomizer], [FormActivatorCommandSet], or [FC debug] (in debug mode only).

What to Send to Support

Prepare the following details (without personal data):

  1. Package version (solution.version from the App Catalog) and documentation version.
  2. Site URL and list ID, form mode (new, edit, display), and steps to reproduce.
  3. Output of Manage-FormCustomizer.ps1 -Action Status.
  4. Browser console output from a load with ?fcdebug=1 enabled (save as text; verify it contains no form data).
  5. Network tab showing failed requests (status, URL, response body).
  6. Form configuration: export from the designer (Export button), or config.json from the list folder.
  7. Configuration storage state (locked, unlocked, designer group) and whether the script policy is enabled.
  8. For licensing: Tenant ID and Site Collection ID from the dialog and the exact error message (do not send the key itself over an insecure channel).