Publishing and validation rules
How a journey is checked and published, what each finding level means, and the full list of review messages with how to fix each one.
Before a journey reaches patients, LeapHealthOS checks it for problems. This page explains how publishing works and what the review findings mean, then lists every finding with the exact message you see and how to fix it. It is for the administrators and implementation staff who build journeys.
When findings appear
The builder checks your journey a moment after every change, and lists what it finds straight away. When you select Publish, the journey is checked again. Some findings appear only at that point, including every check that looks up something outside the journey: whether a role, staff member, team, template, AI flow or target journey exists and is active.
Some findings carry the label Advisory — publish does not check this. They point at likely problems, but publishing never stops for them.
Finding levels
Every finding has one of three levels. The header shows a chip with the count, and selecting it opens the Review before publishing panel.
Level | Group title in the panel | Header chip | Effect on Publish |
|---|---|---|---|
Blocking | To fix before publishing | n to fix (red) | Publish is refused. While a blocking finding marked As you edit in the tables below is listed, the Publish button is disabled. |
Risk | Likely to break a run — check before publishing | n likely to break a run | Publish opens the panel first. You must select Publish anyway to go ahead. |
Warning | Worth a look — you can publish anyway | n to review | None. Publish goes ahead. |
The chip shows the most serious level present. When there are no findings the panel says Nothing to fix — ready to publish.
Risks do not stop a journey from being published, but they can leave a patient stuck or end a journey with no outcome. The panel says so above the Publish anyway button: "These will not stop publishing, but each one can leave a patient stuck or end a journey with no outcome." The button appears only when there are no blocking findings.
Acting on a finding
Each finding in the panel can offer:
- Show on canvas — centres the canvas on the step and selects it.
- Open settings — opens the journey's Settings dialog, for findings about journey settings.
- Open schedules — opens the Schedulers dialog, for findings about recurring schedules.
Findings from a refused Publish stay in the panel until you change the draft. After you fix them, select Publish again.
Publishing a journey
Review the findings
Open the chip in the header, if there is one, and fix anything under To fix before publishing.
Select Publish
Select Publish in the header.
Expected result: If blocking findings or risks are listed, the Review panel opens instead. Otherwise you see Saving journey… while the draft is saved and published.
Accept risks, if any
If the panel lists risks, read each one, then select Publish anyway if you are sure.
Check the result
Expected result: A message confirms Published vN, or Published vN — n things worth a look when there are warnings to review. If publishing was refused, the panel opens with the findings to fix.
Other messages you may see:
- No draft changes to publish — the draft is the same as the latest published version. Nothing new is created.
- Failed to publish journey, or a more specific error — publishing did not complete, for example because of a connection problem or because you do not have permission. See Who can do what in Journeys.
What publishing does
- It creates the next numbered version (v1, v2 and so on) from the current draft. A version is a frozen copy of the steps, connections, recurring schedules, initiation fields and journey settings. It never changes afterwards.
- The journey's status becomes Published and stays so while you keep editing the draft.
- Patients who enrol from now on start on the new version. Patients already on the journey stay on the version they started with. Publishing never moves a running patient to a new version.
A change to Settings alone cannot be published
If you change only the journey's Settings, Publish reports No draft changes to publish and the new settings do not reach patients. Publish them together with a change on the canvas (for example, edit a step's Notes).
There is no Unpublish
You cannot take a published version back. To stop new patients entering, switch off the journey's entry rules (see Entry rules and enrolling patients) or archive the journey. To go back to an earlier design, restore that version and publish it again (see Versions, drafts and simulate).
Review message reference
The tables give each message as the Review panel shows it. In messages, [Step] stands for the label of the step concerned (in a few messages, its type, such as Engage). The Shown column says whether the finding appears as you edit, or only when you select Publish. When you publish, the panel may show a finding you already saw in slightly different words; the fix is the same.
Blocking: journey structure and connections
Message you see | Shown | How to fix |
|---|---|---|
Journey has no Start node | As you edit | Add a Start step from the palette. |
Journey has multiple Start nodes; only one entry is allowed | As you edit | Delete the extra Start steps. |
Something flows into Start — Start can only begin a path. | When you publish | Delete the connection that ends at Start. |
Something flows out of a Close step — Close ends the path. | When you publish | Delete the connection that leaves the Close step. |
Two identical connections exist between the same steps — remove one. | When you publish | Delete one of the duplicate connections. |
A connection carries settings the runtime does not read — re-create it. | When you publish | Delete the connection and draw it again. |
The graph has an unknown step, a self-loop or a dangling connection. | When you publish | Delete the step or connection marked, then redraw it. |
A connection's condition cannot be evaluated — rebuild it. | When you publish | Open the connection, clear its conditions and add them again. |
A Connect step that hands the patient over ends this journey — the step after it can never run. Remove the edge, or spawn the other journey instead. | When you publish | Delete the connection after the Connect step, or change the Connect step so it starts the other journey without handing the patient over. |
Blocking: Start, Close, Pause, Gather and Routine
Message you see | Shown | How to fix |
|---|---|---|
[Step] has no outcome kind — choose success, failure or neutral | As you edit | Open the Close step and choose an Outcome kind. |
A Close step has an outcome kind the runtime does not recognise — choose success, failure or neutral. | When you publish | Open the Close step and choose success, failure or neutral again. |
A Pause has neither a time nor an event to wait for — nothing can ever wake it. | When you publish | Give the Pause a time branch, an event branch, or both. |
A Pause waits on a journey lifecycle event — those cannot be waited on. | When you publish | Remove the event branch that waits on this journey's own events. To wait for another journey, use the linked-journey events. |
[Step] references [event], which is not in the event catalog — pick a catalogued event | As you edit | Pick an event from the Event catalog on the Pause, Routine or interrupt handler. |
[Step] waits for k of n incoming tracks — it can never be satisfied; lower k or connect more tracks | As you edit | Lower k on the Gather, or connect more tracks to it. |
[Step] monitors without a stop condition — add one so the routine can end | As you edit | Add a stop condition to the monitoring Routine. |
[Step] monitors but nothing is set as the reply — pick the event that counts as a response, or every cycle is recorded as a miss | As you edit | Choose the event that counts as the patient's reply. |
Blocking: messages (Reach and templates)
Message you see | Shown | How to fix |
|---|---|---|
[Step]: the step has no message to send | As you edit | Add at least one message to the Reach step. |
[Step]: every message needs a recipient | As you edit | Choose who receives each message. |
[Step]: every message needs a template | As you edit | Choose a template for each message. |
[Step]: every email needs the address it is sent from | As you edit | Choose a sender address in Send from for each email. |
A template of this step uses a variable the step does not fill. Bind every variable of the default template, and use language templates with the same variables in the same order. | When you publish | Fill every template variable on the step. Language versions must use the same variables in the same order as the default template. |
A template on this signing step has no variable for the signing link. Use a template with a variable in the place of the link. | When you publish | Choose a template that has a variable for the signing link. |
This news is given by a person first — put a waiting Engage (call) before the message on every path, or the message is held back. | When you publish | Put an Engage step that waits (a call) before the Reach step on every path, or change the message's news type. The A person first setting is chosen per news type in System Settings, on the Journeys tab, under Message timing policies. |
Blocking: forms (Capture)
Message you see | Shown | How to fix |
|---|---|---|
A Capture step is missing what it needs to deliver its form — open it and fill the marked fields. | When you publish | Open the Capture step and complete the marked fields. |
[Step]: the WhatsApp form needs a template to travel in once the patient has been silent for 24 hours. | As you edit | Choose an approved template for the WhatsApp form. On steps that await several forms, the message names the form. |
The template chosen for a WhatsApp form no longer exists or opens a different form — choose one whose button opens this form. | When you publish | Choose a template whose button opens this same WhatsApp form. |
A staff-surface form can only be sent to a role in this version — change its recipient. | When you publish | Send the staff form to a role. |
A form on a Capture step has no outcome for when it is answered — name one (for example "submitted") so the edges can route the answer. | When you publish | Fill Outcome when answered on every awaited form. |
An answer route names a field its form does not have, or the form could not be read — pick a field from the form, or refresh the form and try again. | When you publish | Pick a question that exists on the form, or reload the page and try again. |
An answer route names a field that not every awaited form on this step has — add the field to each form, or remove the route. | When you publish | Route only on questions that every awaited form has. |
Blocking: staff tasks (Engage and task roles)
Message you see | Shown | How to fix |
|---|---|---|
[Step] is blocking but has no time-fallback edge — a blocking Engage must always have one | As you edit | Despite the wording, a missing connection is not the cause: the Engage step is set to Wait here but has no Time limit. Open the step and, in its Waiting section, set a Time limit, or choose Move on at once if the journey should not wait for the answer. Then connect the Nobody answered in time path on the canvas. |
A waiting Engage step needs “Fallback after” so the wait can end. | When you publish | There is no field called Fallback after. Open the Engage step and set the Time limit in its Waiting section, or choose Move on at once. |
[Step] has no centre configured — pick one so its task reaches that centre's worklist | As you edit | Choose the centre, or attach an AI Aide that fills it. |
Choose the role that receives the task of this step. | When you publish | Choose the role for the task. |
[Step] sends the task to [kind], which the engine does not know — choose a role, a specific person or a team | As you edit | In Send it to, choose A role, A specific person or A team. |
[Step] is sent to a specific person but names nobody — pick the staff member | As you edit | Pick the Person. |
[Step] is sent to a team but names none — pick the team | As you edit | Pick the Team. |
The step names a staff member who does not exist for this tenant — pick another person. | When you publish | Pick a current staff member. |
The step names a team that does not exist for this tenant — pick another team. | When you publish | Pick an existing team. |
A step sends its task to a role that is not set up — choose a role from the list. | When you publish | Choose a role from the list. Roles marked (no permissions yet) cannot get tasks until they are given permissions (see Roles and permissions). This applies to Engage steps, Capture form recipients, Sign coordinators and scheduled tasks. |
Blocking: signing (Sign)
Message you see | Shown | How to fix |
|---|---|---|
[Step]: pick the document to sign | As you edit | Choose the document. |
[Step]: every stage needs at least one signer | As you edit | Add a signer to every stage. |
[Step]: every signer needs a label / every signer needs a person / every signer needs a way to get the link / every signature box needs a width and a height above zero | As you edit | Complete the signer as the message says. |
[Step]: WhatsApp and email signers need a template / WhatsApp and email templates need exactly one signing link | As you edit | Choose a template with exactly one signing-link variable, and a sender for email. |
[Step]: a task can only go to a doctor or staff signer | As you edit | Use task delivery only for staff or doctor signers. |
[Step]: pick who handles signing problems | As you edit | Choose the coordinator role and centre. |
[Step]: set when to follow up on unsigned signers / the follow-up time must be shorter than the signing window | As you edit | Set a follow-up time shorter than the time limit. |
[Step]: give every document value a value | As you edit | Fill every document value. |
[Step]: when one signer signs at a marked place, every signer needs a marked place / two signers cannot sign at the same marked place | As you edit | Give each signer a marked place of its own, or let every signer sign at a corner. |
[Step]: a signer signs at a marked place the document does not have | As you edit | Pick a marked place the document has, or mark it in the document template. |
Use a consent category the clinic has registered as an active consent purpose. | When you publish | Choose an active consent purpose. |
Blocking: appointments
Message you see | Shown | How to fix |
|---|---|---|
An Appointment step is missing its service, provider or slot — it would fail when it runs. | When you publish | Set the service, the provider (not needed for Service appointments) and a slot policy or exact times. |
This version can only book appointments — cancel and reschedule are not available yet. | When you publish | Set Action to Book. |
An Appointment step names an appointment type the clinic does not have — choose one from the list. | When you publish | Choose an appointment type on the step or in its booking profile. |
An Appointment step books a priced service without a payment collection setting — choose how the fee is collected. | When you publish | Set Payment collection. |
Blocking: linking journeys (Connect, Involve, Tell)
Message you see | Shown | How to fix |
|---|---|---|
[Step]: choose the journey this step hands the patient to. | As you edit | Choose the target journey on the Connect step. |
A Connect step targets a journey that is not active for this tenant. | When you publish | Choose an active journey. An archived journey is no longer a valid target for Connect or Involve. |
[Step]: choose the journey, how to find the person, a role name for each side, and the task role when nobody is found. | As you edit | Complete the Involve step. |
[Step]: name the signal this step sends. | As you edit | Enter a Signal name. |
Blocking: AI steps (Produce and AI Aide)
Message you see | Shown | How to fix |
|---|---|---|
A Produce step references a flow that is not live and published. | When you publish | Publish and activate the AI flow, or choose another. |
An AI Aide points at a flow that is not live and published. | When you publish | Publish and activate the AI flow, or choose another. |
[Step] attaches a [kind] aide, which this version cannot run yet — use a flow or a team | As you edit | Set the AI Aide to a flow or a team. |
An AI Aide output is not mapped to a field on the step it is attached to. | When you publish | A field on the step reads an AI output that no attached aide fills. Map it on the AI Aide, or give the field another source. |
AI aide maps an output onto a path the host node does not have; a mapping reads host path <- aide output path, so this one would write nothing | When you publish | Remove or correct the mapping on the AI Aide. |
An AI Aide is wired with a flow edge — aides attach with the dashed connector. | When you publish | Delete the connection and attach the aide with the dashed connector. |
An AI Aide is attached to a step that cannot host one. | When you publish | Attach it to a Reach, Capture, Engage, Appointment, Connect or Produce step. |
A step has more than one AI Aide attached — keep one. | When you publish | Remove the extra AI Aides. |
An AI Aide is attached to more than one step — keep one. | When you publish | Keep one attachment per AI Aide. |
One blocking finding is also labelled Advisory
The finding that begins "AI aide maps an output onto a path the host node does not have" stops publishing, even though the panel also labels it Advisory — publish does not check this. Fix it before you publish.
Blocking: lookups, journey settings and schedules
Message you see | Shown | How to fix |
|---|---|---|
A lookup uses a strategy that is not allowed for what it looks up — pick another source. | When you publish | Choose a strategy that is allowed for that kind of record. |
A lookup strategy is missing a field it needs, such as its key. | When you publish | Complete the strategy. |
A related-person lookup names a relation the record cannot hold — choose one from the list. | When you publish | Choose a relation from the list. |
DPDP handler for patient.consent_revoked ([target]) must reach a Close node — its sub-flow has no path to Close | As you edit | Use Open settings. Under Global events & interrupt handlers, set the Action of every Consent revoked entry to Close the journey. |
Consent revoked must close the journey — every entry for it has to be “Close”. | When you publish | The same fix: set the Action of every Consent revoked entry to Close the journey. |
A schedule is missing the fields its action needs. | When you publish | Use Open schedules and complete the schedule's action. Scheduled tasks cannot wait. |
Risks: likely to break a run
These do not stop publishing. When a risk is listed before you publish, Publish asks you to confirm with Publish anyway. Risks found only when you publish are reported afterwards, in the Published vN — n things worth a look message and the panel.
Message you see | Shown | How to fix |
|---|---|---|
[Step] has n incoming branches; use a Gather node for parallel convergence | As you edit | Parallel tracks rejoin at an ordinary step, which then runs once per track. Put a Gather in front of it. See The builder canvas. |
Loop ([steps]) has no exit edge — instances can never leave it | As you edit | Add a connection out of the loop, onward or to a Close step. |
A Pause that waits silently for events has no event branch — nothing can ever wake it. | When you publish | Add an event branch, or set the missing-anchor policy to Fall back to activation moment. |
Open tasks are set to escalate when the journey closes, but Settings names no escalation role — they would be left where they are. | When you publish | Either name a role in Escalate closed journeys' open tasks to (System Settings, Journeys tab, Staff & signing), or use Open settings and change Open tasks policy under On instance close. |
[Step] has conditioned edges with no default — completion may activate nothing and the branch ends silently | As you edit (advisory) | Add a default connection. |
[Step] has no way forward — a journey that reaches it stops there with no outcome. Connect it onward or to a Close | As you edit (advisory) | Connect the step onward or to a Close step. |
[Step] offers n answers but no connection reads any of them — whatever staff answer, the journey takes the same path | As you edit (advisory) | Route the Engage answers with the Outcome field on its connections. |
[Step] reads context.nodes.[name] but no upstream node is named "[name]" | As you edit (advisory) | The step reads a step that does not exist or was renamed. Correct the reference. |
[Step] reads context.nodes.[name] but "[name]" is not upstream of this step — on a parallel branch the value may not exist yet | As you edit (advisory) | Read only steps that come before this one on its path, or join the tracks with a Gather first. |
[Step] uses a value from [other step], but the journey can reach [Step] without passing [other step] — on that path the value is empty | As you edit (advisory) | Make sure every path passes the step whose value you use, or plan for the empty case. |
Warnings
Message you see | Shown | How to fix |
|---|---|---|
[Step] is not connected to the journey | As you edit | Connect the step, or delete it. |
[Step] can never activate — no path from Start reaches it | As you edit | Connect it to a path that starts at Start. |
A condition reads a step that is not on the graph. | When you publish | Rebuild the condition with a step that exists. |
The journey this step involves involves this one back. Each start attaches to the same case, so nothing loops — check that both are wanted. | When you publish | No change needed if both journeys really should involve each other. |
Advisory warnings
These are listed under Worth a look — you can publish anyway with the label Advisory — publish does not check this. Publishing does not stop for them, but each points at something likely to go wrong when the journey runs.
Message you see | How to fix |
|---|---|
Node name "[Step]" is used more than once — names must be unique because downstream expressions read context.nodes.<name> | Rename one of the steps. |
[Step] has a default edge beside an unconditioned edge — the default can never fire | Despite the wording, the default does fire: whenever none of the step's conditions match, the patient follows the default and the plain connection at the same time. If the plain connection should always run, remove the default (untick Default edge or delete that connection). If the plain connection should run only in some cases, give it an Outcome or a condition. See The builder canvas. |
[Step]'s time branch has no default or unconditioned edge — this node can hang | Every connection the time branch could take carries an extra outcome or condition, so when the time comes none of them may fire. Add a connection with Pause branch set to Time branch and no outcome or conditions, or add a default connection. |
[Step] has no timeout branch — convergence may wait forever | Set a Timeout on the Gather. |
[Step] declares outcome "[outcome]" but no outgoing edge is bound to it | Connect a path for that outcome (Engage answers, Capture outcomes), or add a default. |
[Step] awaits forms with no timeout — a blocking gateway must be bounded by an offset or anchor | Set a Time limit on the Capture step. |
[Step] awaits forms with no fallback outcome — set one so the gateway has a path on timeout | Fill Path taken at the limit. |
[Step] actively delivers "[form]" but no recipient is set — pick who receives the form | Choose the form's Recipient. |
[Step] delivers "[form]" passively, but no surface carries journey linkage yet — publish is blocked until passive support lands | Use active delivery. Passive delivery is not available yet. |
[Step] routes on form "[form]", but its questions could not be loaded — routing cannot be validated until the form resolves | Reload the page. If the message stays, check that the form still exists. |
[Step] routes on question "[question]", but the form "[form]" has no such question | Pick a question the form has. |
[Step] uses a variant this version cannot deliver ([variant]) — pick a live variant | Choose another form type. |
[Step] resolves a recipient only via sticky/initiation — the engine can't tell patient from staff and silently skips it; add a patient or role-scoped strategy | Add a patient or role-based lookup to the recipient. |
[Step]'s required field "[field]" has no source — set a value or map an aide output | Fill the field. |
[Step] requires "[field]" but no source is set — map an aide output or set a value | Fill the field, or map it on the attached AI Aide. |
[Step] references a booking profile that no longer exists — pick an existing profile or clear it | Choose an existing booking profile. |
[Step] inherits fields from a booking profile — runtime profile merge is pending the engine; override the inherited fields to publish for now | Set the inherited fields on the step itself. |
[Step] reads initial.[field], which is not declared in the initiation schema — the launch form could never satisfy it | Add the field to the journey's initiation fields in Settings, or correct the reference. |
Initiation field "[field]" is optional and never read by the graph | Remove the field, or use it. |
[Step]'s "[field]" has no way to resolve — add at least one strategy | Add a lookup strategy. |
[Step]'s "[field]" has no source selected — pick how it resolves | Complete the lookup strategy. |
[Step]'s "[field]" can match more than one — choose which one to use | Set Which one. |
[Step]'s "[field]" can still match more than one entity — narrow the selection or it will be picked deterministically | Narrow the selection if the choice matters. |
[Step] has incomplete output mappings — every mapping needs a flow output and a parent field | Complete every mapping on the AI Aide. |
[Step] attaches flow "[flow]", but no such flow exists in this workspace — its outputs cannot be validated | Choose an existing AI flow. |
[Step] maps "[output]", but the attached flow "[flow]" declares no such output | Map an output the flow has. |
[Step] leaves required output "[output]" of flow "[flow]" unmapped | Map the required output. |
[Step] maps an aide output into "[field]", which is not an input this node accepts | Map onto a field the step has. |
[Step] maps "[output]" into "[field]", but the value type may not match what this field expects | Check that the AI flow returns the right kind of value for that field. |
Related pages
- The builder canvas and how connections work
- Waiting, time limits and reminders
- Versions, drafts and simulate
- Node reference overview
Last updated on
Waiting, time limits and reminders
Which journey steps wait, how their time limits and reminders work, what happens at the limit, and the clinic defaults that apply.
Versions, drafts and simulate
How drafts and published versions relate, how to view and restore an earlier version, and how to dry-run a journey with Simulate.