What this covers
Where Scriptor writes logs, which log to look at first for a given class of problem, and how to raise verbosity for a diagnostic session. The goal is not to enumerate every error Scriptor can produce; it is to give you a triage map so the next time something is broken you know where to start.
Walkthrough
The three logs that matter
| Log | Path | What lives there |
|---|---|---|
| Scriptor application log | data/logs/scriptor.log |
PSR-3 records Scriptor emits: lifecycle events, caught exceptions, plugin boot failures, the things Scriptor wrote on purpose. |
| PHP / web-server error log | platform-dependent (see below) | PHP fatal errors that crashed before Scriptor's logger ran. Stack traces of Uncaught Error, parse errors in an included file, OOM. |
| Browser developer console | F12 in the browser, "Console" tab | JS errors in the editor's FilePond, Preview, or sortable tree. CSP violations. Failed XHRs to /editor/api/upload. |
You usually read them in the order of the table: Scriptor's log first (it caught it), the web-server log when Scriptor did not catch it (because nothing was running), the browser console when the breakage is on the editor's client side.
Find the Scriptor application log
The default path is data/logs/scriptor.log under the project
root. The logging.path key in
data/settings/scriptor-config.php is the source of truth;
the override file in data/settings/custom.scriptor-config.php
can point it somewhere else.
Tail it while reproducing a problem:
tail -F data/logs/scriptor.log
A typical info-level record looks like:
[2026-05-25 11:42:17] scriptor.INFO: PluginManager booted 4 plugins
[2026-05-25 11:42:18] scriptor.INFO: PageRepository resolved /about
A failure looks like:
[2026-05-25 11:43:02] scriptor.ERROR: Plugin boot failed: bigins/scriptor-markdown-pages threw RuntimeException ...
Find the PHP / web-server error log
Path depends on how you run PHP:
| Platform | Typical path |
|---|---|
| ServBay (the maintainer's local dev) | /Applications/ServBay/package/var/log/php/<version>/errors.log |
| Apache + mod_php | error_log directive in httpd.conf, often /var/log/apache2/error.log |
| Nginx + PHP-FPM | PHP-FPM's error_log directive in www.conf, often /var/log/php-fpm/error.log; nginx's own access/error logs in /var/log/nginx/ |
| Docker (compose stack) | docker compose logs scriptor (PHP-FPM stdout) and docker compose logs nginx (web server) |
| PHP's built-in server | the terminal you started php -S in |
When in doubt, php --ini prints the active php.ini file
and that file's error_log directive points at the right
place.
Find the browser developer console
Open the editor in the browser, hit F12 (or Cmd-Opt-I on macOS), select the Console tab. Reproduce the problem; JS errors appear with a stack trace and (usually) a link to the source file.
For FilePond upload failures specifically, also check the
Network tab and filter for upload; the failed POST to
/editor/api/upload shows there with the response body
Scriptor returned (typically a JSON error message).
Raise log verbosity
The default logging.level is info. To see more, set it to
debug in data/settings/custom.scriptor-config.php:
return [
'logging' => [
'level' => 'debug',
],
];
Save the file; the next request writes at debug level
without a restart. Reset it to info when you are done;
debug is verbose and the log will fill up faster.
The PSR-3 levels are, low to high: debug, info, notice,
warning, error, critical, alert, emergency. Setting
level to a given level filters out everything below it.
Symptom map
| Symptom | Read first | Then |
|---|---|---|
| 500 error on the frontend with a blank page | PHP / web-server log | data/logs/scriptor.log |
| 500 error with a Scriptor-styled error page | data/logs/scriptor.log |
PHP log if the application log is silent |
| Login form rejects credentials I know are correct | data/logs/scriptor.log (failed-attempt records) |
The LoginAttempts rate-limit; see First boot and admin login troubleshooting |
| FilePond upload stuck or failing | Browser Network tab | data/logs/scriptor.log for the /api/upload POST handler |
| Editor preview overlay shows raw markdown | Browser Console | Look for missing editor-assets/scripts/remarkable/ (script not loaded) |
| Page saves succeed but the change does not show on the frontend | None first; suspect cache | Hard-reload (Ctrl-Shift-R); flush a reverse-proxy cache if you have one |
| Plugin's sidebar item disappeared | data/logs/scriptor.log for a plugin-boot error |
Installed plugins troubleshooting |
composer update succeeded but the site is broken |
Browser console (theme errors), data/logs/scriptor.log (boot errors), PHP log (fatal errors before Scriptor) |
The release notes for the version you moved to |
Rotate logs that grew too large
Scriptor's logger appends to data/logs/scriptor.log without
rotation. On a busy site, the file grows indefinitely. Two
patterns:
-
OS-level logrotate:
# /etc/logrotate.d/scriptor /opt/scriptor-cms.dev/data/logs/scriptor.log { weekly rotate 8 compress delaycompress missingok notifempty copytruncate }copytruncatekeeps Scriptor's file handle valid (no reload needed) at the cost of a brief window where the log is being copied. -
Manual rotation: when the file is big and you do not want to set up logrotate, copy it aside and truncate:
cp data/logs/scriptor.log data/logs/scriptor.log.$(date +%Y%m%d).bak : > data/logs/scriptor.logThen
gzipthe backup if you want to keep it.
What to check after a diagnostic session
- You reset
logging.levelback toinfoif you raised it. - The log file is back at a manageable size (you rotated, or the next rotation will catch it).
- The fix you made for the original symptom held up across a reproduction.
Troubleshooting
data/logs/scriptor.log does not exist
Either nothing has been logged yet (a brand-new install with no requests handled), or the path is wrong, or the directory is not writable.
- Make a request to the site; check again.
cat data/settings/scriptor-config.php | grep -A2 logging: what path doeslogging.pathresolve to?ls -ld data/logs/: is the directory writable by the web server's user?
Editor opens but the Network tab shows 401 on every XHR
Your session expired or the editor lost its login state. Refresh the editor (a full reload, not just the tab). If that returns you to the login form, you are no longer authenticated; log in again.
Browser Console shows "Refused to load ... violates CSP"
The site's Content Security Policy is blocking an asset that Scriptor's editor needs. Three common cases:
- The CSP forbids
script-src 'self'for an editor asset. The editor needs to load its own JS from/editor-assets/; adjust the policy. - A plugin loads assets from a different origin. Add that origin to the appropriate CSP directive.
- Inline scripts. Some editor flows use inline JS; add
'unsafe-inline'toscript-src(acceptable trade-off for an admin UI; do not put it on the public-facing CSP).
The deployed security-headers baseline ships a policy that works for the default editor; deviations from that baseline need testing.
I cannot find anything in the log, but the site is still broken
The error is somewhere the application log does not see. Check the PHP / web-server error log next. If both are silent, the issue is upstream of PHP (the web server is serving the wrong file, the reverse proxy is caching a stale response, the load balancer is sending the request to the wrong backend).
See also
- Backup and restore: backup before you start poking at logs in production
- Updating Scriptor: the update path that most often surfaces a log-worthy regression
- Site settings and theme switch: where
logging.levelandlogging.pathlive in the config - First boot and admin login: the rate-limiter records the application log surfaces
docs/install.mdin the Scriptor repo: what the install command writes (and therefore what the application log will look like on a fresh install)