Serializing exceptions with JSON.serialize
Why is this an issue?
Calling JSON.serialize() or JSON.serializePretty() on an exception now always fails at runtime. Previously, this behavior was inconsistent—sometimes succeeding, sometimes failing depending on the exception subtype. From API version 63.0, these calls fail consistently.
The rule applies to any value whose static type is Exception, System.Exception, or a subclass — user-defined or platform-provided. Calls where the type cannot be resolved are not flagged.
Examples
Example of incorrect code:
try {
// Some operation
} catch (Exception e) {
String errorJson = JSON.serialize(e); // Fails at runtime
System.debug(errorJson);
}
Example of correct code:
try {
// Some operation
} catch (Exception e) {
// Extract the information you need
Map<String, Object> errorInfo = new Map<String, Object>{
'message' => e.getMessage(),
'type' => e.getTypeName(),
'stackTrace' => e.getStackTraceString(),
'lineNumber' => e.getLineNumber()
};
String errorJson = JSON.serialize(errorInfo);
System.debug(errorJson);
}
How can I fix violations?
The right fix depends on what consumes the resulting string:
Logging or display only — replace the call with
String.valueOf(e)ore.getMessage(). This is usually the smallest change.} catch (Exception e) {
System.debug(String.valueOf(e));
}Structured JSON output — build a serializable wrapper (a
Map<String, Object>or a small DTO) with the fields you need, then serialize the wrapper, as shown in the correct example above.
When should I disable this rule?
Disable or dismiss specific instances when:
The class is pinned to an API version below 63.0 and you are intentionally relying on the old, subtype-dependent behavior.
The flagged call is in a test class where the exception is constructed locally and the runtime failure is part of what the test asserts.
In production code targeting API 63.0 or later, the call will always fail at runtime, so the rule should generally stay enabled.
Resources
