
Customer Journey Analytics (CJA) offers powerful capabilities for understanding customer experiences across multiple touchpoints. However, my initial hands-on experience revealed several challenges and insights that I wish I had known beforehand. In this post, I will share four key lessons about data ingestion, identity mapping, historical data ingestion, and handling product data within Adobe Experience Platform (AEP). If you are navigating the complexities of CJA, these takeaways may help you avoid common pitfalls.
1. Data Ingestion: Strict Rules and Hidden Challenges
One of the first obstacles I encountered was how much stricter data ingestion is in CJA compared to Adobe Analytics. In AEP, the XDM schema serves as the single source of truth, meaning every attribute must adhere precisely to its defined format; otherwise, it will be rejected. Here are some key examples:
- Null values are not allowed. Any null attribute is immediately declined.
- Strict type enforcement. If an attribute is defined as a string but receives an integer (or vice versa), the data is rejected.
In contrast, Adobe Analytics historically collected data even when it was incorrectly formatted. While this leniency was convenient, enforcing strict data quality in AEP ensures cleaner and more reliable datasets.
Identifying Ingestion Errors in AEP
Pinpointing the root cause of ingestion errors in AEP is not always straightforward. For example, if you are ingesting data from multiple Launch properties into a single dataset, errors can arise from various sources. Unfortunately, the dataset UI in AEP does not provide sufficient information to identify the exact cause. Troubleshooting requires a robust validation process. The two primary locations for error diagnosis are:
- Sources > Dataflow > Preview error diagnostic: This gives you a preview of up to 100 errors.

- API Logs: Using tools like Postman, you can access more granular logs using the data access api (read more)
There is an insightful article by Barry Mann on Medium that explores the wide variety of ingestion errors in detail.
Bonus Insight: Namespace Priority Feature (Beta)
If you are using the namespace priority feature (currently in beta as of February 18, 2025), you may encounter an error where identifier attributes cannot be empty strings. This is especially problematic when using Adobe Launch (Tags) as a tag manager. Launch may return null or an empty string for data elements that are not explicitly set. In our case, identity attributes were set when users were authenticated but absent when they were not. The solution was to adjust the data element logic in Launch to return undefined
when not set, resolving the issue.

2. CJA and Identity Mapping: Not Exactly Best Friends
I initially assumed that CJA handled identity mapping similarly to Adobe’s Customer Data Platform (CDP), where:
- An experience dataset includes a primary ID (e.g., ECID) and a secondary ID (e.g., hashed customer number).
- A profile dataset includes the primary ID (e.g., hashed customer number).
- Due to the identity graph, profiles are stitched together, merging experience data and profile data for a holistic customer view.
Unfortunately, CJA does not support identity graphs in the same way. When configuring datasets in CJA, you can only map the primary ID, meaning that CJA does not recognize the identity graph.
Stitching to the Rescue
Field-Based Stitching (or Graph-Based Stitching, depending on your contract) provides a workaround. Once configured and ingested into CJA, it allows you to join datasets based on a transient ID (e.g., hashed customer number) and a persistent ID (e.g., ECID), effectively enabling the expected behavior. However, it is crucial to understand that Field-Based Stitching creates an additional schema and dataset. Any changes to your original schema must also be applied to the stitched schema, adding an extra layer of complexity.
3. Historical Data Ingestion via Adobe Analytics Source Connector: Easier Said Than Done
My initial plan was to use the Adobe Analytics Source Connector (AASC) to ingest historical data. Since this creates two dataflows (one for historical and one for continuous data) and a single dataset, I assumed I could delete the continuous dataflow (as we are already using WEB SDK for ingestion) while retaining the historical data. Wrong!
If you delete the continuous dataflow, it also deletes the dataset, resulting in the loss of historical data. Additionally, using AASC means you must keep eVars and props in CJA because the Adobe Analytics Experience field group is required. While it is possible to map your custom XDM schema, this approach unnecessarily transfers the entire eVar/prop structure into AEP, which is not ideal.
The Alternative: Datafeeds
We opted for Datafeeds instead, which allowed us to bypass the limitations of AASC. If you are unfamiliar with Datafeeds, they provide processed analytics data, where each row represents an occurrence, including post-processed eVars (post_evar
). Datafeeds also include lookup files for dimensions like country, browser, or operating system, which must be classified separately. We managed the entire ETL process using Python scripts, which:
- Exported Datafeeds.
- Classified the exported file using lookup files.
- Imported the processed data into AEP.
This approach proved more flexible but introduced additional challenges with product data ingestion, as detailed below.
4. Handling Product Data with Datafeeds: Proceed with Caution
While Datafeeds offer greater control, ingesting product data into AEP posed several challenges. We required multiple iterations before finding a reliable solution due to two key issues:
1. Sensitivity of Calculated Functions in AEP Data Prep
AEP provides Adobe Analytics functions (e.g., aa_get
functions) to extract information from the product string. However:
- If the product string is empty (common for non-eCommerce interactions), it results in a NullPointer error, preventing further processing.

product_list
is unavailable, the null check does not function correctly.Solution: We created an attribute (isProductData) that determines whether a row contains eCommerce data (yes/no
) and applied it to the iif()
condition to bypass the issue.
2. Formatting Errors in the Product String
- Due to some issues on developer side, some product names contained semicolons, which disrupted processing. Worse, if such errors appeared within the first 10 rows, the entire file was rejected.

These issues highlight the importance of robust data validation before ingestion, particularly for product-related datasets.
Conclusion: Navigating CJA’s Complexities
Transitioning to CJA was more challenging than anticipated due to its strict data requirements, identity mapping limitations, and complexities in product data handling. However, its powerful analytical capabilities make the effort worthwhile.
Key Takeaways:
- Validate your data rigorously before ingestion to prevent processing failures.
- Understand identity mapping limitations and leverage Field-Based Stitching when needed.
- Plan your historical data ingestion strategy carefully—Datafeeds provide a flexible alternative to AASC.
- Test product data ingestion thoroughly, as calculated functions are sensitive to formatting errors.
Despite the challenges, mastering CJA unlocks valuable insights into customer behavior. Investing the time to understand its complexities will ultimately pay off.