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 in segments: section)
- External ref:
segment: ref:Segment Name — see journey skill for ref: limitations
Related Skills
- journey - Full journey creation and management
- validate-segment - Segment rule validation