Troubleshooting
Find your symptom below. If an error includes a code or diagnostic path, use the error reference for its exact meaning.
Private packages cannot be installed
Section titled “Private packages cannot be installed”Composer and your JavaScript package manager install InertiaX only after you connect the InertiaX registry with the Connect the registry commands on your portal’s Registry keys page.
| Symptom | Check |
|---|---|
Could not find a matching version of package inertiax/laravel-table |
Composer isn’t connected to the InertiaX registry: run the portal’s Composer commands in your application’s directory |
404 Not Found - GET https://registry.npmjs.org/@inertiax%2freact-table (other package managers print a similar 404 or Not found for an @inertiax package) |
Your package manager looks for @inertiax packages on the public npm registry: run the portal’s commands for it |
401 Unauthorized |
The key is active in the portal and hasn’t been rotated or revoked since you ran its commands |
403 Forbidden |
Your InertiaX access is active and the key isn’t revoked |
| Package not found | Package name, registry endpoint, and authentication; private registries may conceal unauthorized packages |
| Works locally, fails in CI | Install job can access the protected secret and creates authentication before installation |
See Early access for keeping keys safe locally and in CI, and Request help for what to send if the portal’s commands still fail.
The table is unstyled
Section titled “The table is unstyled”Import the stylesheet in your browser entry point:
React
import '@inertiax/react-table/styles.css';If it is already imported, check that the built CSS loads in the browser. base.css supplies only
the functional foundation; your application must add its own visual styling.
See Styling.
The table is empty or shows the wrong records
Section titled “The table is empty or shows the wrong records”An empty table with headers is a valid rendered result. Run the source query in the same request context, then check the table’s search, filters, page, and page size. Also check that React reads the intended prop.
For unexpected records, correct the server query scope. For stale page links after records disappear, use the table’s reset action to return to page 1.
The Inertia prop is missing or invalid
Section titled “The Inertia prop is missing or invalid”Use the same name in PHP and React:
Laravel
UsersTable::make('users')React
<AppTable prop="users" />INERTIAX_INERTIA_PROP_MISSING means the named page prop is absent.
INERTIAX_TABLE_QUERY_PROP_INVALID means it is not a complete valid table response. Inspect the page
props and return the table builder as shown in Your first table.
A component mismatch means a response for one table reached another table’s session. Use distinct names for multiple instances.
The provider is missing
Section titled “The provider is missing”Check that the page uses the shared persistent layout containing InertiaProvider and TableProvider,
as shown in Installation. Table hooks must also run inside a table renderer.
See Direct envelope for the lower-level renderer owners.
Search, sorting, or filtering is missing
Section titled “Search, sorting, or filtering is missing”Enable the capability on the column:
Laravel
TextColumn::make('name')->searchable()->sortable()->filterable();Also check table-level sorting(false) or autoFilters(false) settings. For Eloquent and collections,
searchable non-text columns need a custom search strategy.
Custom sources require searchable columns to keep type('text') and handle search in the source;
see Custom-source search.
An Inertia generation fails
Section titled “An Inertia generation fails”Use matching 2.x or matching 3.x Laravel and React adapters. Check the actual resolutions in both lockfiles, then rebuild the frontend after changing versions. See Compatibility.
Back returns to the same page after opening a table link
Section titled “Back returns to the same page after opening a table link”This is an edge case in native Inertia URL handling that can also occur without InertiaX. Investigate it only if the first Back navigation unexpectedly leaves you on the same page.
Compare the URL you opened with the initial Inertia page URL. The query values may match while their order or encoding differs:
Opened: /invoices?invoices_search=alice&invoices_page=2Response: /invoices?invoices_page=2&invoices_search=aliceLaravel’s default Inertia page URL uses a query string normalized by Symfony. Inertia compares
that URL with the browser URL as strings; a mismatch can add a history entry during initialization.
Capture the original path and query before Inertia initializes, then compare it with the initial
page URL from usePage().url. By component mount, the address bar may already have changed.
If you confirm this mismatch, optionally add this line inside your existing
app/Http/Middleware/HandleInertiaRequests.php class:
Laravel
use \InertiaX\Http\Middleware\Concerns\PreservesInertiaUrl;The helper uses Inertia’s supported page URL resolver
to retain raw query order/encoding and Laravel’s base path, including a correctly configured trusted
proxy prefix. It affects every Inertia page URL. If you already define urlResolver(), review and
merge the behavior yourself; a class method takes precedence over the trait. Do not decode the
query string. URL fragments stay in the browser and are not sent to PHP.
Upstream discussion
Section titled “Upstream discussion”The URL encoding discussion in inertia-laravel #663 and URL readability issue #707 are closed. In #707, a maintainer recommends customizing the resolver; merged PR #739 introduced that API. These links cover related URL normalization and customization, not a dedicated report or confirmed fix for the exact initial Back-button symptom above.
Tested versions
The extra entry reproduced without InertiaX in Chromium with Inertia Core 2.3.18, 3.6.1, and 3.8.0. The resolver was verified with Inertia Laravel 2.0.25 and 3.3.1; Chromium checks preserved Back/Forward navigation and a URL fragment. Other browsers and deployments need their own verification.
A reload or request fails
Section titled “A reload or request fails”For INERTIAX_INERTIA_RELOAD_FAILED or INERTIAX_TABLE_INTEGRATION_DISPATCH_FAILED, inspect the
original cause, browser response, Laravel logs, requested prop name, and protocol diagnostic.
Retry is available for a failed request; invalid definitions or payloads need correction first.
A newer interaction or unmount can cancel an older request. If an older result replaces newer state, check that one integration owns the table session and the Inertia generations match. See Request lifecycle.
A custom renderer uses fallback
Section titled “A custom renderer uses fallback”Match the Laravel type('acme/role') of a column, or valueType('acme/role') of a filter clause,
to the React registration’s key: 'acme/role' and check the registration scope.
INERTIAX_CATALOG_FALLBACK_USED identifies the missing type.
See Registration & diagnostics to make it fatal in development.
A collection callback fails
Section titled “A collection callback fails”An Eloquent-only callback cannot run against a collection. Implement collection behavior and
declare DataSourceKind::Collection, or keep an Eloquent source.
See Custom query behavior.
Row identity or selection fails
Section titled “Row identity or selection fails”Declare the row key as a column, including for empty results. Every row must have a unique key.
For custom keys on possibly empty model collections, set rowKey() explicitly.
See Row identity.
Selection contains only IDs in the current result page. Page changes can therefore clear it; see Selection.
An inferred column has the wrong type
Section titled “An inferred column has the wrong type”Use an explicit column such as NumberColumn::make('score'). Model casts take precedence over
schema inference, and unsupported casts fall back to text. A tinyint(1) column becomes a boolean
column, so a value other than 0 and 1 fails with
Boolean column [level] cannot cast int to boolean.
Declare such a column explicitly, for example as NumberColumn::make('level'). See
Automatic columns.
The envelope is rejected
Section titled “The envelope is rejected”INERTIAX_PROTOCOL_VERSION_UNSUPPORTED indicates an unsupported protocol major.
INERTIAX_PROTOCOL_DECODE_FAILED indicates invalid data or table semantics. Inspect the first
reported path against the protocol reference.
Align incompatible packages, or correct the producer or custom pipeline. Do not edit
protocolVersion to bypass validation.
Request help
Section titled “Request help”Email contact@inertiax.dev with the diagnostic details.
PHP autocomplete
Section titled “PHP autocomplete”InertiaX ships PHP types and PHPDoc for builder completion. No IDE-helper generation is required.
In VS Code, use a PHP language server such as Intelephense; the official Laravel extension adds
Laravel-specific assistance. PhpStorm also reads the bundled ide.json for built-in identifier
suggestions. Custom namespaced types remain valid.
UsersTable::make('users') returns a Table builder, so methods such as data() are available.
Custom builder classes should declare their generic relationship as shown in
Table inheritance.
Field names inside TextColumn::make('…') are not automatically tied to a model. A reusable table
can receive different queries or collections through data(). The Laravel VS Code extension does
not currently read InertiaX’s PhpStorm metadata.
A callback cannot resolve a scalar parameter
Section titled “A callback cannot resolve a scalar parameter”Use the callback’s context name, rather than the domain field name:
Laravel
// For a column named total_cents:->transformUsing(fn (float $value): float => $value / 100)fn (int $cents) fails because cents is not supplied. The exception lists available names;
see Callback context. A named value with an incompatible
type also fails. For example, NumberColumn casts to float by default; use float $value or
choose numberCast('int') before requiring int $value.