Integrating Salesforce with third-party web services is a common requirement in cloud development. However, during data conversion, developers frequently run into runtime parsing exceptions. Understanding standard JSON parsing errors helps you debug integration issues quickly and write more resilient Apex code.
1. System.JSONException: Malformed JSON
The most common runtime exception is the malformed JSON error. This occurs when the external API returns an invalid JSON string (e.g., missing double quotes around keys, trailing commas, or missing brackets). When Apex tries to parse it, it throws a System.JSONException: Malformed JSON... exception.
**How to resolve**: Validate that the external system returns compliant RFC 8259 JSON. You can also utilize automated tool formats like **json2apex's Auto-Fix tool** to scan, detect, and correct formatting syntax errors locally during testing.
2. Reserved Apex Keywords as JSON Keys
Salesforce has reserved keywords (e.g., class, public, private, currency, limit). If an external API returns a JSON field using one of these names, you cannot name your Apex variable identically:
// THIS WILL NOT COMPILE
public class ResponseWrapper {
public String class; // 'class' is a reserved keyword
}
**How to resolve**: Rename the variable in your Apex class (e.g., to clazz or class_x) and use search-and-replace strings before deserialization, or parse the payload dynamically using untyped parsing. **json2apex** automatically detects these reserved keywords and prefixes them with an underscore (e.g. _class) to avoid compilation failures.
3. JSON_PARSER_ERROR: Expected Array, Got Object
This mismatch occurs when your Apex wrapper models a field as a List (array), but the API returns a single JSON object instead (or vice versa). Salesforce's deserialization is strict and fails immediately:
// Apex Wrapper expects a list
public class Response {
public List<Contact> contacts;
}
// API returns a single object instead of an array
// Payload: {"contacts": {"name": "John"}}
**How to resolve**: Adjust your Apex class structure to match the API response. If the API is dynamic (sometimes returning a single item and other times a list), you must parse the payload untyped first and write logic to handle the different node types manually.
4. Decimal vs. Integer Mismatch
If your Apex wrapper declares a variable as an Integer, but the inbound API sends a float value (e.g., 45.50), the deserialization engine will throw a type mismatch exception.
**How to resolve**: In your generated wrapper classes, declare numerical variables as Decimal or Double rather than Integer unless you are 100% guaranteed to receive non-floating integers. Declaring fields as Decimal is safer and prevents runtime crashes.
Summary
Most Salesforce integration failures are caused by discrepancies between the API JSON structure and the Apex class definition. By avoiding reserved keywords, declaring numerical fields as Decimal, verifying array nodes, and parsing untyped Map structures when dynamic keys exist, you protect your Salesforce ecosystem from unexpected exceptions.