Troubleshooting
/truss returns 404
Two things can cause this, and both return 404 on purpose:
- Truss is disabled. It is enabled in
localonly by default. In any other environment, setTRUSS_ENABLED=true. - The
viewTrussgate denied you. In non-local environments the gate is consulted. Make sure your user is allowed, either viaTRUSS_ALLOWED_EMAILSor your own gate definition, and that you are logged in. See the Authorization guide.
The page loads but the diagram is blank
- Check the browser console and network tab. If an asset request (for example
truss.js) failed, ensure requests can reach/{prefix}/assets/.... - Under a strict Content-Security-Policy, allow
script-src 'self',style-src 'self' 'unsafe-inline', andfont-src 'self'. Mermaid needs'unsafe-inline'instyle-src. See Configuration. - If you set
TRUSS_MERMAID_URLto a CDN, make sure your CSP allows that host inscript-src.
Every table renders as an empty box
The diagram draws and every table is there, but each one is empty: no columns, no types, no keys, and no relationship lines between them. php artisan truss:export --format=json shows the same thing, with "columns": [], "primary_key": [] and "foreign_keys": [] on every table.
The cause is a table prefix on the connection, set as 'prefix' => 'portal_' in config/database.php or through DB_PREFIX. Before Truss v1.8.3, introspection passed the table names the database reports, which already carry the prefix, back into Laravel’s schema methods, and those prepend the prefix a second time. Truss was asking for portal_portal_users, which exists nowhere, so every lookup came back empty and nothing in the output explained why.
Upgrade to v1.8.3 or later. There is nothing to configure: prefixed connections are introspected in real database names, and table names render with the prefix, exactly as the database stores them. A schema shared between applications works too, including tables that do not carry the prefix at all.
A banner says the SQLite fallback was used
Truss could not reach the target database connection, so it replayed your migrations on an in-memory SQLite database and drew that instead. Column types may be approximate, and any migration that fails on SQLite is skipped and listed. Fix the connection to see the real schema.
A connection is not visualizable
If you set truss.connections, only the connections you listed are visualizable. A request for any other connection returns 404. Add the connection to the list, or leave connections empty to use the application’s default.
”Could not load schema (HTTP 500)”
The dashboard shell renders, but the diagram area shows this over an empty canvas.
The usual cause is the schema-diff baseline landing on a remote disk. Before Truss v1.8.2, diff.disk followed your application’s default disk, so an app with FILESYSTEM_DISK=s3 (or any remote default) tried to read truss/baselines/{connection}.json through that adapter. A failure there returned a 500 for the whole endpoint, even though the diagram itself needs no filesystem access. The exception in your log looks like:
League\Flysystem\UnableToCheckDirectoryExistenceUnable to check existence for: truss/baselines/mysql.jsonFix it with one line, then clear the config cache:
TRUSS_DIFF_DISK=localphp artisan config:clearOn v1.8.2 and later a baseline problem cannot take the dashboard down. The disk defaults to local, and a baseline that cannot be read costs you the “Changes” panel and nothing else: you get a notice saying so, and the diagram, doctor and exports are unaffected. Upgrading is the better fix.
If you would rather not have Truss write to disk at all, set TRUSS_DIFF_ENABLED=false. See the Schema diff guide.
The other cause is a cache store Truss cannot reach. CACHE_STORE=database is Laravel’s own default and its cache table is not always there yet: a partial migrate --path= batch, a migrate:rollback past that table, or a secondary connection migrated first all leave it missing, and a Redis or Memcached server can simply be down. Before v1.8.4 the failure escaped the schema endpoint as a 500, with a trace that names the cache table and nothing about Truss:
SQLSTATE[HY000]: General error: 1 no such table: cacheOn v1.8.4 and later this cannot take the dashboard down either. The structure is read live instead of from the cache, so the diagram is complete, and a notice says it will stay slow until the store is usable again. Run php artisan truss:rebuild to confirm the cause: it is the one command that reports a failed write, with the store’s own error and a non-zero exit.
php artisan migrate fails and the trace mentions Truss
Truss refreshes its snapshot on the MigrationsEnded event, which fires after your migrations have already committed. Anything thrown there fails the Artisan command on work that succeeded, and Laravel does not swallow listener exceptions. Two dependencies could do that, and both are now fixed:
- The diff baseline on disk, before v1.8.2. An unreachable or misconfigured disk (
FILESYSTEM_DISK=s3with the old default) escaped into the migration. SetTRUSS_DIFF_DISK=local, or upgrade. - The cache store, before v1.8.4. An unusable store failed the migration on the rebuild, which matters most in a deploy step running
migrate --force.
From v1.8.4 the listener never throws, whichever dependency is down: it logs a warning and leaves the snapshot stale, which php artisan truss:rebuild fixes once the cause is sorted. If a migration still fails with Truss in the trace, please open an issue with the trace, because that is a bug.
Changes to the schema are not showing
The snapshot is cached (cache.ttl, default one hour) and rebuilt automatically after migrations. If you changed the schema another way, force a refresh:
php artisan truss:rebuildA table is missing from the diagram
Check excluded_tables (global and per-connection). Excluded tables are removed server-side and never reach the browser. Framework tables such as migrations, sessions, cache, and jobs are excluded by default.
Labels lose their last character in Firefox on Windows
Fixed in v1.10.0. Upgrade with composer update albertoarena/laravel-truss.
Every label was cut in proportion to its length: table names, column names and column types alike, losing roughly the last character on longer ones. It showed only in Firefox on Windows. Chrome on the same machine was fine, and so was Firefox on macOS or Linux.
The diagram was drawn before the IBM Plex Mono webfont had loaded, so the label boxes were sized against whichever monospace font the system provided, then repainted in IBM Plex Mono once it arrived. On Windows that fallback is Consolas, which is about 9 percent narrower, so every label painted wider than the box it was measured into. The boxes carry no spare room, so the overflow was clipped. Elsewhere the fallback happens to have the same character width as IBM Plex Mono, which is why it never showed there.
If you cannot upgrade yet, opening the page with the browser’s developer tools already open avoids it, since the extra startup time lets the font arrive first. That is a diagnostic, not a fix.