validate-journey
Journey YAML Validation
tdx journey validate # Validate all journey YAML files locally
tdx journey validate path/to/journey.yml # Validate specific file
tdx journey push --dry-run # Preview changes before push
Validation Checks
Structure Validation
| Code | Level | Description |
|---|---|---|
MISSING_NAME |
error | Journey missing name field |
MISSING_STAGES |
error | Journey has no stages defined |
MISSING_GOAL |
warning | Journey has no goal defined |
DUPLICATE_LATEST |
error | Multiple versions/journeys have latest: true |
TOO_MANY_STAGES |
error | More than 8 stages |
MISSING_ENTRY_CRITERIA |
error | Stage missing entry_criteria |
MISSING_MILESTONE |
error | Non-last stage missing milestone |
MISSING_EXIT_CRITERIA |
warning | Stage has no exit_criteria |
Step Count Validation
| Code | Level | Description |
|---|---|---|
INSUFFICIENT_STEPS |
error | Stage has 0-1 steps (needs at least 2) |
FEW_STEPS |
warning | Stage has 2-3 steps (may be too simple) |
Step Validation
| Code | Level | Description |
|---|---|---|
DUPLICATE_STEP_NAME |
error | Two steps share the same name |
INVALID_NEXT_REFERENCE |
error | next points to non-existent step |
MISSING_WAIT_PARAMS |
error | Wait step missing duration+unit or condition |
MISSING_SEGMENT_REFERENCE |
error | Condition wait or branch missing segment |
MISSING_ACTIVATION_REF |
error | Activation step missing with.activation |
MISSING_CONDITIONS |
error | Decision point or AB test missing branches/variants |
INVALID_AB_TEST_PERCENTAGES |
error | AB test variant percentages don't sum to 100 |
INVALID_JUMP_TARGET |
error | Jump step missing target.journey or target.stage |
END_STEP_HAS_NEXT_OR_WITH |
error | End step has next or with field |
Flow Control Validation
| Code | Level | Description |
|---|---|---|
MISSING_END_STEP |
error | Stage has no end step |
CONVERGENCE_WITHOUT_MERGE |
error | Multiple paths converge on a non-merge step |
SINGLE_INPUT_MERGE |
warning | Merge step has only one input path |
MERGE_TO_MERGE_CHAIN |
error | Merge step's next is another merge step |
BRANCH_DIRECTLY_TO_MERGE |
error | Decision/A/B test/condition wait branch goes directly to merge (no action) |
API Constraints (not checked by tdx journey validate, but rejected by the API)
| Constraint | Description |
|---|---|
| Branch must have activation | Every decision_point/ab_test/condition wait branch MUST have an activation step before merge |
| Wait after activation | A wait step must follow every activation step. If activation → merge, place wait after merge |
Schema Validation (Zod)
| Code | Level | Description |
|---|---|---|
JOURNEY_SCHEMA_ERROR |
error | Journey YAML structure doesn't match expected schema (invalid types, missing required fields, unknown enum values) |
ACTIVATION_SCHEMA_ERROR |
error | Activation definition has invalid structure (missing name or connection, invalid schedule type, etc.) |
Reference Validation
| Code | Level | Description |
|---|---|---|
MISSING_ACTIVATION_DEFINITION |
error | Activation key not found in activations: section |
UNUSED_EMBEDDED_SEGMENT |
warning | Segment defined in segments: but never referenced |
Required Structure
type: journey # Required
name: Journey Name
reentry: no_reentry # no_reentry | reentry_unless_goal_achieved | reentry_always
goal: # Recommended (warning if missing)
name: Goal Name
segment: goal-segment # Embedded segment (defined in segments: section)
journeys:
- state: draft
stages:
- name: Stage Name
entry_criteria: # Required
name: Entry Name
segment: entry-segment
exit_criteria: # Recommended (warning if missing)
- name: Exit Name
segment: exit-segment
milestone: # Required for non-last stages
name: Milestone Name
segment: milestone-segment
steps: # At least 2 steps required (4+ recommended)
- type: activation
name: Send Email
next: End Stage
with:
activation: email-key
- type: end
name: End Stage
Limits: Max 8 stages (validated locally). API constraints: 120 events/journey, 70 events/stage, 30 versions
Step Types Quick Reference
| Type | Required with |
Notes |
|---|---|---|
wait |
duration + unit, OR condition, OR wait_until |
Condition wait: NO top-level next: (paths inside condition). Optional: days_of_week |
activation |
activation |
key from activations section |
decision_point |
branches[] |
each needs segment, next |
ab_test |
variants[] |
percentages must sum to 100 |
merge |
(none) | required when multiple paths converge |
jump |
target with journey, stage |
target is an object |
end |
(none) | no next or with allowed |
Important: next: is a direct field on step, not inside with:. The value must be the exact step name as written (e.g., Send Email), not a slugified version (e.g., ).send-email
Design Rules (not caught by validator)
- Condition wait paths MUST lead to different actions — if both paths do the same thing, use duration wait instead
- Every branch (decision_point, ab_test, condition wait) should perform a meaningful, distinct action
- Prefer flat branching over nested branching — inner branches must merge before joining outer branch
- A wait step must follow every activation step (place after merge if activation → merge)
- Frequency capping: wait between activations; avoid >1 message/day/channel
- Consent/Suppression: use entry_criteria/exit_criteria segments for opt-in and removal
Flow Control Rules
# Pattern: decision → actions → merge → wait → end
- type: decision_point
name: Check Status
with:
branches:
- name: Active
segment: active_users
next: Send Offer # Must NOT point directly to merge
- name: Others
excluded: true
next: Send Reminder
- type: activation
name: Send Offer
next: Rejoin
with: { activation: offer }
- type: activation
name: Send Reminder
next: Rejoin
with: { activation: reminder }
- type: merge
name: Rejoin # Required: multiple paths need merge
next: Wait After Rejoin # Must NOT point to another merge
- type: wait
name: Wait After Rejoin
next: end
with: { duration: 1, unit: day }
- type: end
name: End Stage
Condition Wait Format
Condition wait has NO top-level next: — paths are inside condition:
with:
condition:
segment: made-purchase
next: matched-path # Path when condition met
timeout:
duration: 14
unit: day
next: timeout-path # Path when max wait exceeded
See journey skill for all wait step options (duration, wait_until, days_of_week).
Segment References
- Embedded (recommended):
segment: my-segment(defined insegments:section) - External ref:
segment: ref:Segment Name— see journey skill forref:limitations
Related Skills
- journey - Full journey creation and management
- validate-segment - Segment rule validation
More from treasure-data/td-skills
pytd
Expert assistance for using pytd (Python SDK) to query and import data with Treasure Data. Use this skill when users need help with Python-based data analysis, querying Presto/Hive, importing pandas DataFrames, bulk data uploads, or integrating TD with Python analytical workflows.
20workflow
Manages TD workflows using `tdx wf` commands. Covers project sync (pull/push/clone), running workflows, monitoring sessions/attempts, task timeline visualization, retry/kill operations, and secrets management. Use when users need to manage, monitor, or debug Treasure Workflow projects via tdx CLI.
3journey
Load when the client wants to create, edit, or manage a CDP customer journey. Use for building journey YAML with segments, activations, and stage steps, modifying journey stages or flow logic (decision points, condition waits, A/B tests), or pushing journey changes to Treasure Data. Also load when the client wants to analyze journey performance, query journey tables, create journey dashboards, or generate journey action reports.
2parent-segment-analysis
Query and analyze CDP parent segment database data. Use `tdx ps desc -o` to get output database schema, then query customers and behavior tables. Use when exploring parent segment data, building reports, or analyzing customer attributes and behaviors.
2connector-config
Writes connector_config for segment/journey activations using `tdx connection schema <type>` to discover available fields. Use when configuring activations - always run schema command first to see connector-specific fields.
2trino
TD Trino SQL with TD-specific functions (td_interval, td_time_range, td_time_string, td_sessionize). Use for time-based filtering, partition pruning, and TD query patterns.
2