Dynamic fields from payload arrays fail in AJO push notifications
In Adobe Journey Optimizer (AJO), push notifications fail to render dynamic fields from payload arrays—like "callerName"
—even though the same data works in Email and SMS. Fields may appear blank or show special characters as hexadecimal codes. To fix this, simplify your expressions, flatten the payload if possible, and ensure UTF-8 encoding is preserved end to end.
Description description
Environment
Product: Adobe Journey Optimizer (AJO)
Channels: Push (iOS via APNs, Android via FCM)
Issue/Symptoms
Dynamic personalization fails for array-based fields in push notifications.
Steps to Reproduce
-
Create a journey in AJO that triggers a push notification.
-
Pass a payload where the personalization attribute is part of an array, for example:
code language-none { "attribute_list_group": [ { "name": "callerName", "value": "Bill Robert" } ] }
-
In the push notification title/body, configure a personalization expression:
code language-none #each context.journey.events.[ eventId] ._tmobile.decision_detail_group.attribute_list_group as |container| {%#if contains(container.name, "callerName")%} container.value {%/if%} /each
-
Send the notification.
Observed: On mobile, the field appears blank or shows hexadecimal codes for special characters. The same expression works correctly in Email and SMS channels.
Cause
- AJO’s push channel parser is stricter than Email and SMS. It expects flat string values and has limited support for loops, complex expressions, and non-string data types in the title or body.
- The templating and helper syntax (Handlebars vs. Nunjucks/Liquid) may not be equally supported in push notification fields.
- Special characters in the payload may be encoded as hexadecimal (e.g.,
\u2019
) during serialization. Push services and some device apps may not decode these sequences and instead display them as-is. - Push services like APNs and FCM enforce UTF-8 encoding, reject control characters, and may misrender, drop, or reject messages with malformed or escaped sequences.
- AJO only supports properly typed strings. If a dynamic expression resolves to an object, malformed string, or array, the push message may silently fail or be truncated.
Resolution resolution
- Remove all whitespace and newlines from your looping expression. Use a compact version like this:
#each context.journey.events.[ eventId] ._tmobile.decision_detail_group.attribute_list_group as |container|{%#if contains(container.name, "callerName")%}container.value{%/if%}/each
This resolved the issue for Latin characters in a current customer implementation. - If possible, flatten the payload by moving
callerName
to a top-level field. Then useevent.callerName
directly in the push template. - If flattening isn’t an option, make sure the correct array index is selected and test the personalization preview in AJO to confirm rendering.
- Ensure UTF-8 encoding is preserved at every stage—from the source system to AJO processing to the push service. Avoid double-encoding or escaping special characters.
- If special characters still appear as hexadecimal, it’s likely a limitation of the push channel or device rendering. AJO doesn’t currently offer a setting to force decoding of these characters on the device.
Handling Special Characters and Unicode in Payloads
When passing strings in JWT payloads or personalization data, always ensure you properly encode or escape special characters and validate Unicode input. Improper encoding can lead to rendering issues, parsing failures, or blank fields in push notifications.
Proper JSON String Encoding & Character Escaping
JSON requires certain characters to be escaped to ensure the payload is parsed correctly:
Example:
{
"message": "Hello\\nWorld! She said, \\\"Hi there!\\\"."
}
Escaping in Code
- JavaScript:
JSON.stringify("Hello\nWorld! She said, \"Hi there!\".")
- Python:
json.dumps("Hello\nWorld! She said, \"Hi there!\".")
Unicode Handling
JSON supports Unicode via UTF-8 encoding. Characters can be represented directly or using \uXXXX
notation:
{
"emoji": ":grinning:",
"currency": "€",
"chinese": "你好",
"heart": "\u2764"
}
Example Payload with Special Characters:
{
"scopes": [ "read", "write", "special:áéíóú", "quote:\"test\""] ,
"user": "John\\nDoe"
}
Unsupported or Sensitive Characters in JWT Modules
Payloads must be valid JSON. Avoid:
- Unescaped double quotes or newlines outside strings
- Control characters (ASCII codes 0–31, except whitespace)
- Non-UTF-8 bytes
Refer to RFC 8259 Section 7 for JSON character encoding rules.
Known Issues:
- Commas, periods, and backslashes in field names
- Unescaped quotes breaking parsing
- Control characters and invalid Unicode sequences
Best Practices for Unicode and Encoding
-
Always set the header:
Content-Type: application/json; charset=UTF-8
-
Use standard libraries for serialization:
JSON.stringify()
in JavaScriptjson.dumps()
in Python
-
Validate payloads using tools like JSONLint
-
Avoid double-escaping or double-serializing
-
Test with multilingual and emoji characters to ensure proper rendering
Related reading
- Personalization in Push Notifications in AJO Guide
- Personalization Use Cases in AJO Guide