Troubleshooting
Every Flowmark error and modeling check message, what causes it and how to fix it.
You can see two kinds of messages:
- Flowmark errors stop the text from being read. The Flowmark pane's header shows the message with its line number, and so does the Problems panel. The diagram keeps its last working version until you fix the line. Select the message to jump to the line.
- Modeling checks run on a diagram that was read without errors. They point out paths that can't finish, missing gateways and other modeling problems. They're listed in the Problems panel, and the diagram still updates. See Modeling checks for each one in detail.
Each Flowmark error below shows the text that causes it, then the message the editor shows.
Lines the editor doesn't understand
The kind is capitalized or missing
Kinds must be lowercase. process, lanes, lane, pool, doc:, note: and on: can be written in any case, but node kinds can't.
start Claim received
User Review claimLine 2: Expected a node kind (start, end, catch, throw, task, user, service, manual, script, rule, send, receive, call, sub, xor, and, or, eventgw), lane, arrow or blank line; got "User Review claim".
The same message appears for any line that doesn't start with a kind, process, lane, lanes, pool, doc:, note:, on:, => or <=, and has no ->. Fix the kind, or turn the line into a comment with //.
An indented line comes before any node
Arrows, on:, note: and message lines belong to the node above them, so they can't come first. (A doc: line can: before the first node it documents the process.)
process Claims
-> Review claimLine 2: An arrow must follow a node.
The same line in other forms gives:
on:lines: "on: must follow a task."note:lines: "note: must follow a node."=>and<=lines: "=> must follow a node." or "<= must follow a node."
Move the line under the node it belongs to.
Arrows
An arrow has no target
start Claim received
xor Complete?
yes ->Line 3: Write arrows as
label [condition] (default) -> Target.
Write the name or #id of the node the arrow goes to after ->. See Flows and labels.
An arrow points to a node that isn't declared
Every target needs its own line somewhere in the text.
start Claim received
xor Complete?
yes -> Pay claim
no -> Return claim
send Return claim
end Claim returnedLine 3: No node named "Pay claim". Declare it on its own line (e.g.
task Pay claim).
Check the spelling, or add the missing node. With an id, such as -> #paid, the message is "No node with id #paid." Add #paid to the end of the node's line.
An arrow's target name is used twice
start Order received
xor Payment method?
card -> Notify customer
invoice -> Notify customer
send Notify customer
end Order paid
send Notify customer
end Invoice sentLine 3: "Notify customer" names 2 nodes; give one an #id and point to it.
Give each node an id and point to the ids, as in Use #ids when names aren't enough.
An arrow points back to the start event
Nothing can flow into a start event. To loop back, point to the first step after it, with a merge gateway in front of that step.
start Claim received
user Review claim
xor Complete?
yes -> Claim paid
no -> Claim received
end Claim paidLine 5: Arrows cannot point to the start event "Claim received".
See Approval with rework for a loop that works.
The same arrow appears twice
start Claim received
xor Complete?
yes -> Pay claim
ok -> Pay claim
service Pay claimLine 4: Duplicate arrow to "Pay claim".
Two flows can't connect the same two nodes. Keep one of the lines.
Events and boundary events
An event type is on a task
Only events take a type after a colon:
start Claim received
user:timer(P2D) Review claimLine 2: Only events take an event type (got user:timer).
For a deadline on a task, use a boundary event: on:timer(P2D) on the line under the task. See Boundary events.
~ is on something other than a boundary event
start Claim received
catch~timer(P2D) Two days passedLine 2: Use
~only on boundary events (on~timer).
Use : instead, as in catch:timer(P2D).
The event type is misspelled
start:email Claim receivedLine 1: Unknown event type "email".
The types are message, timer, error, signal, conditional, escalation, terminate and compensation. See Events.
On a boundary event the message lists the types you can use:
start Claim received
user Review claim
on:timeout(P2D) Review overdue -> Send reminderLine 3: Unknown event "timeout". Use one of: message, timer, error, signal, conditional, escalation, terminate, compensation.
A boundary event with no type gets the same message, naming the first word of its name, because that word is read as the type.
A boundary event has nothing where the type goes
start Claim received
user Review claim
on:(P2D) Review overdue -> Send reminderLine 3: Write a boundary event as
on:timer(P2D) Name -> Target, with the event type right afteron:.
Ids
An id appears twice
start Claim received #received
user Review claim #receivedLine 2: Id #received is used twice.
Each id can appear once, across nodes and pools. Change one of them.
Pools and messages
A pool line has no name
process Order tracking
poolLine 2: Write pools as
pool Name, orpool Name (below)to draw it below the process.
Write the party's name after pool.
A pool is declared twice
pool Carrier
pool carrier (below)Line 2: Pool "carrier" is declared twice.
Pool names ignore capitalization. Keep one pool line.
A pool has two ids
pool Carrier #carrier (below) #shipperLine 1: Give a pool one #id.
A message line can't be read
A message needs a pool after => or <=:
start Order received
send Send confirmation
=>: Order confirmationLine 3: Write messages as
=> Pool: message(sent) or<= Pool: message(received).
A message line has -> in it
pool Sales -> EU #sales_eu
start Order received
send Send order
=> Sales -> EU: OrderLine 5: A message line can't contain "->". Name a pool whose name has "->" by its id (
=> #id: message), and leave "->" out of message names.
Write => #sales_eu: Order. See Pools and messages.
A message names a pool that isn't declared
start Order received
send Book pickup
=> Carrier: Pickup requestLine 3: No pool named "Carrier". Declare it with
pool Carrier(drawn above the process) orpool Carrier (below).
Add the pool line near the top. With an id, such as => #carrier: Pickup request, the message is "No pool with id #carrier."
The same message appears twice
pool Carrier
start Order received
send Book pickup
=> Carrier: Pickup request
=> Carrier: Pickup requestLine 6: Duplicate message "Pickup request" to "Carrier".
A step can send a pool several messages, but each needs a different name. A received message reads "from" instead of "to".
Steps connect that you meant to keep apart
Two mistakes parse without an error but draw something you didn't mean.
A missing blank line between branches. Here Pay claim connects to Return claim on the next line, so paid claims also get returned:
start Claim received
xor Complete?
yes -> Pay claim
no (default) -> Return claim
service Pay claim
send Return claim
end Claim closedThe checks catch this one: "Return claim" (Task_ReturnClaim) has 2 incoming flows (implicit merge). Put a blank line before each branch, as in the examples.
An arrow on a node line. Any line with -> in it is read as an arrow from the node above. So user Review claim -> Pay claim doesn't declare a task: it adds an arrow labeled "user Review claim", and the review step never appears. Declare the node on one line and put the arrow on the next.
Modeling check messages
In these messages, "Review claim" (Task_ReviewClaim) stands for the name and id of the element the message is about. The fixes are for Flowmark; Modeling checks explains each one and how to fix it on the canvas.
Errors
| Message | What to do |
|---|---|
| The process has no start event. | Add a start line at the beginning. |
| The process has no end event. | Add an end line at the end of each path. |
| "Review claim" (Task_ReviewClaim) isn't connected yet: it has no incoming or outgoing sequence flow. | Usually blank lines above and below it, or the line above is an end event: point an arrow to it and one from it, or delete it. |
| "Review claim" (Task_ReviewClaim) has no outgoing sequence flow yet (dead end). | Add an arrow or the next step under it, or an end line. Often a boundary event with no -> Target. |
| "Review claim" (Task_ReviewClaim) has no incoming sequence flow yet. | Point an arrow to it, or remove the blank line above it. |
| "Review claim" (Task_ReviewClaim) cannot be reached from a start event. | It sits in a loop nothing leads into: point an arrow from the process into the loop, or delete it. |
| "Review claim" (Task_ReviewClaim) never leads to an end event. | It sits in a loop with no way out: give the loop an arrow toward an end line. |
| Boundary event "Review overdue" (…) is attached to "Approved?" (…), which isn't an activity. | Move the on: line under a task, call activity or sub-process. |
| Event-based gateway "Wait" (…) must lead to catch events or receive tasks, not "Send reminder" (…). | Make each target of the eventgw a catch event or a receive task. See Waiting for a reply. |
| "Joined" (…) joins branches of an exclusive split, so it waits forever for the branches that weren't taken (deadlock). Merge them with an exclusive gateway. | Change the merging and to xor. |
| The branches of "Fraud suspected?" (…) meet at parallel gateway join, which waits for every flow into it, but only one of those branches is taken, so it waits forever (deadlock). … | Merge the decision's branches with xor #screened and point that one flow to the and join. See Parallel work. |
| A path after parallel join decided loops back into only some of the branches it joins, so on the next pass it waits forever for the others (deadlock). … | Point the loop to an xor merge after the and join, or to one before the parallel split. |
| Message "Order" (…): "Approved?" (…) is a gateway; gateways can't send or receive messages. Use a send or receive task, or a message event. | Move the => or <= line under a task or a message event. |
| Message "Order" (…): "Order received" (…) is a start event, so it can only receive messages. | Use <= on start and catch events. The same message says "catch event" for a catch line. |
| Message "Order" (…): "Order shipped" (…) is an end event, so it can only send messages. | Use => on end and throw events. The same message says "a throw event" for a throw line. |
| Message "Order" (…): "Week started" (…) is a timer event; make it a message event to receive messages. | Change the event's type to message, as in start:message, or move the message to a task. |
Warnings
| Message | What to do |
|---|---|
| Activity Task_1 has no name. Use verb + object, e.g. "Approve invoice". | Add a name after the kind: user Approve invoice. |
| "Review claim" (Task_ReviewClaim) has 2 incoming flows (implicit merge). Merge with a gateway first. | Add xor #merge (or and #merge for parallel paths) on the line above and point the arrows to it. Often a missing blank line between branches. A catch event that a loop returns to needs the same merge. |
| "Review claim" (Task_ReviewClaim) has 2 outgoing flows (implicit split). Use a gateway to make the split explicit. | Put the arrows under an xor or and after the task instead. |
| Timer "Two days passed" (…) has no duration, date or cycle. Set one, e.g. P2D or PT4H. | Add the value in parentheses: catch:timer(P2D). See Events. |
| Gateway "Approved?" (…) neither splits nor merges yet. Add its branches, or remove it. | Delete the gateway line, or give it two or more arrows out. |
| Flow Flow_1 leaving decision "Approved?" (…) has no label or condition. | Label each arrow, as in yes -> Pay claim, or add (default) to one. |
| Flow Flow_1 leaves a parallel gateway; its condition is ignored. | Remove the [condition], or use xor or or. |
| "Joined" (…) merges branches from a parallel split; use a parallel gateway to join them. | Change the merging xor to and. |
| The branches of parallel split fork never meet again. Join them with a parallel gateway. … | Point every branch to one and join. For a reminder or deadline, move the timer onto the task that keeps the work open (on~timer or on:timer) and delete the waiting branch. See Deadlines and reminders. |
| 2 elements are named "Notify customer" (…). Give each a distinct name. | Rename one of them. |
| The diagram has 21 activities. Keep one level of detail (about 5-20): move a detailed area into a call activity or sub-process. | Replace a detailed area with a call or sub step. |
Style notes
Style notes are suggestions; it's fine to leave some.
| Message | What to do |
|---|---|
| Activity "Review" (…): prefer verb + object naming, e.g. "Review application". | Name it as a verb and an object. |
| Start event StartEvent_1 has no name. Name events as a state, e.g. "Order received". | Add a name. The same message says "End event" for an end line. |
| Decision gateway Gateway_1 has no name. Phrase it as a question, e.g. "Amount > 10k?". | Name the gateway as a question. Merges can keep only an #id. |
| Gateway "Approved?" (…) both merges and splits. Separate merge and split gateways read more clearly. | Add a separate merge gateway in front of it. |
| "Quote sent" (…) is a message event, but no message goes to an outside pool. Add one (=> Pool: message), or change its type. | Add a => line under it, or change its kind. Only once the diagram has pools. |
| "Order received" (…) is a message event, but no message comes from an outside pool. Add one (<= Pool: message), or change its type. | Add a <= line under it, or change its kind. Only once the diagram has pools. |
| "Send invoice to Customer" (…) names the pool "Customer" but sends it no message. Add one (=> Customer: message). | Add the => line. A send or receive step is only noted when its name mentions an outside pool. |
| "Receive quote from Carrier" (…) names the pool "Carrier" but receives no message from it. Add one (<= Carrier: message). | Add the <= line. |
| Pool "Carrier" has no messages. Show what the process sends it or receives from it, or remove it. | Add a message to or from it, or delete the pool line. |
| Lane "Finance" is empty. | Move steps into it, or remove it from the lanes line. |
| The diagram is empty. | Start with a start line. |