Error Logging
Choose where errors are recorded, what is captured with them, and why browser output must never be on in production.
Error Logging Modes
Error Logging Mode decides where the platform records errors. It is one setting with four values and it is worth choosing deliberately.
Where to find it
Architect Panel → Configuration:
- Site Settings — Error Logging Mode, and the stack trace settings alongside it
Architect Panel → Activity:
- Error Log — errors recorded to the database
The four modes
- Database — errors are written to the platform's own error log and read from the Architect Panel.
- PHP error log — errors go to the server's error log, alongside everything else the server records.
- Both — written to each.
- None — errors are not recorded at all.
Which to choose
Database is the right default for most installations. Errors are searchable and filterable in the panel, they are visible to administrators who have no server access, and they are included in the database backup.
Both suits installations with a server team who want errors in their existing server monitoring as well.
PHP error log alone makes sense where an administrator should not see application errors, or where the volume is high enough that you would rather not carry it in the database.
Never choose None on a live system
It is available for a reason — a short-lived load test, a diagnostic exercise — but a production system that records no errors cannot be supported. Problems become anecdotes, intermittent faults become unprovable, and the first real evidence of a failure is a user describing it from memory.
If volume is the concern, address the errors rather than the recording.
Output Errors to Browser must stay off
There is a separate setting that sends errors to the browser. It exists for local development and must be disabled on any production site.
The reason is specific rather than general caution: an error and its stack trace can contain sensitive data — values being processed at the time, connection details, occasionally credentials. Displaying that to whoever triggered the error hands it to them, and the people most likely to trigger unusual errors are the people probing your site.
Check this setting after any configuration restore or environment clone. It is the classic thing to have been enabled on the development instance and copied.
Pretty errors are development only
The same reasoning applies to enriched error display. Anything that makes an error more readable makes it more readable to everybody.
Review the log, do not merely collect it
An error log nobody reads is storage. Make it a routine — after every deployment, and once a week otherwise. What you are looking for is a new error type or a change in rate, not a zero count.
Worked example
An installation runs in database mode. After a release, the weekly check shows a new error type appearing about forty times a day, all from one integration endpoint. It had been failing silently for six days because the integration retried and eventually succeeded. It is fixed before anybody notices a delay — which is only possible because the errors were being recorded and read.
Recommendations
- Use database mode unless you have a reason not to.
- Never run production with recording disabled.
- Verify browser output is off after any environment clone.
- Read the log weekly, looking for new types rather than totals.
Capturing Stack Traces
An error message tells you what went wrong. A stack trace tells you how the code arrived there — and that is usually the harder half of the question.
Where to find it
Architect Panel → Configuration:
- Site Settings — Capture Stack Trace, and the limit and argument settings
Architect Panel → Activity:
- Error Log — the entries traces are attached to
What a trace gives you
The chain of calls that led to the failure. "Undefined value" on its own is nearly useless when the same function is reached from a dozen places; the trace tells you which route was taken this time.
For intermittent problems it is often the only useful evidence, because the conditions cannot be reproduced on demand.
Turning it on
Capture Stack Trace enables it. It is worth having on: the cost is a modest amount of storage per error, and on a healthy system there are not many errors.
The reasonable exception is an installation logging errors in very high volume — but that is a signal to fix the errors rather than to stop describing them.
Traces contain data
This is the important caveat, and it is why the related settings exist. A trace records the path through the code, and depending on configuration it can also record the values being passed along that path.
That makes the error log more sensitive than it first appears. Treat access to it as you would access to the data it describes, and see the article on including arguments before turning that option on.
Use it with the error log, not instead of it
The trace explains one occurrence. The pattern across the log — when it started, how often, from which addresses — explains the problem. Investigations that read one trace closely and never look at the surrounding entries usually fix a symptom.
Deployment is the moment that matters
Most new error types appear immediately after a change. A trace captured in the first hours after a deployment is worth more than the same trace found a fortnight later, because the change that caused it is still obvious.
Worked example
An intermittent failure appears a few times a week with a message that identifies nothing. With traces enabled, three occurrences show the same route into the failing function — from a scheduled task rather than from the interface, which nobody had considered. The cause is a record the task processes that the interface never produces. Without a trace, the investigation had been stuck for a month.
Recommendations
- Keep trace capture enabled.
- Read the log around a trace, not just the trace.
- Check the log soon after every deployment.
- Treat the error log as sensitive once traces are on.
Including Arguments in Traces
Include Arguments in Stacktrace records the values passed to each function in the trace, not just the function names. It is the most useful diagnostic setting available and the most dangerous.
Where to find it
Architect Panel → Configuration:
- Site Settings — Include Arguments in Stacktrace
Architect Panel → Activity:
- Error Log — where the captured arguments are stored
Architect Panel → Security:
- Permissions — who can reach the error log
Why it helps so much
Knowing that a function failed is one thing; knowing it failed on a particular value is usually the answer. A date in an unexpected format, an empty identifier, a string longer than assumed — arguments turn "this sometimes fails" into "this fails on that".
Why it is dangerous
Arguments are the actual data being processed. Whatever was flowing through the failing code — personal data, a password being verified, an API token being used, the contents of a message — is what would otherwise be written into the error log.
An error log is typically less protected than the data it now contains, and it is often kept far longer.
Redaction is applied
The platform does not simply dump what it captured. Before a trace is stored or printed, it is redacted: values whose parameter names indicate a secret are replaced, secret-looking keys are removed recursively from nested structures, and the live object attached to each frame — which would carry the caller's entire private state — is discarded.
This is done deliberately and early, before anything logs, prints or encodes the trace.
Redaction is not a guarantee
It removes what it can identify. It cannot identify a customer's name in a parameter called value, or personal data inside a payload being parsed.
So the honest position is: redaction reliably keeps credentials out, and does not promise to keep personal data out. Those are different assurances and the difference matters when deciding whether to enable this in production.
Recommended use
- Development and test — on. The diagnostic value is high and the data is not real.
- Production — off by default. Turn it on deliberately, to investigate a specific problem, and turn it off again.
Treating it as a temporary diagnostic rather than a standing setting gives you the benefit at the moment you need it without accumulating years of captured values.
If you leave it on
Restrict error log access to named administrators, set a short retention on the error log specifically, and include it in your record of what personal data you hold. All three are cheap; none of them happens by default.
Worked example
A payment integration fails for a small number of customers. Arguments are enabled for one afternoon, three failures are captured, and the traces show an address line containing a character the provider rejects. The setting is turned off the same day and the captured entries are removed once the fix is confirmed — so the diagnosis is obtained without leaving a standing collection of customer addresses in the error log.
Recommendations
- Off in production by default, on in development.
- Enable it as a temporary diagnostic and turn it off again.
- Do not rely on redaction for personal data — it protects credentials.
- Restrict and time-limit error log access if it stays on.