Quick Overview
Sometimes the :finish
, qualifier (or its :finish-all
& :finish-any
counterparts for families) were used erroneously in Cylc 7 workflows where :succeed
(or its :succeed-all
& :succeed-any
counterparts) would have been more appropriate.
This may cause validation failures when you try to upgrade to Cylc 8, similar to this one like this:
GraphParseError: Output foo:succeed can't be both required and optional
If you encounter errors like this where :finish
triggers are present, consider whether you want to permit the task to fail and allow the workflow to move on to the next task.
If you don’t, then :finish
was probably a mistake, switch it for :succeeded
and the error will go away.
Otherwise have a look at the graph branching section of the migration guide for upgrade advice.
Full Explanation
:succeeded
vs :finished
In Cylc graphs, if you don’t specify a qualifier, Cylc assumes you mean :succeed
.
For example this:
foo => bar
Is shorthand for this:
foo:succeed => bar
There is a special qualifier called :finished
which is shorthand for :succeed
or :fail
.
For example this:
foo:finished => bar
If equivalent to this:
foo:succeed | foo:fail => bar # | means "or"
The same goes for the :finished-all
and :finished-any
qualifiers which can be used with families.
Misconception
In Cylc 7, :finished
was sometimes used by mistake in situations where :succeed
would have been more appropriate. Especially with family triggers (e.g. FAMILY:finish-all
) where the difference between :finish-all
and :succeed-all
might not have been so obvious to the person who wrote the workflow.
Issues Upgrading :finish
to Cylc 8
Cylc 8 is smart enough to know that :succeed
and :fail
are opposite outcomes, so it doesn’t allow them to both be required.
For example this workflow:
foo:succeed => bar # foo must succeed
foo:failed => baz # foo must fail
Will fail validation:
$ cylc validate .
GraphParseError: Opposite outputs foo:succeeded and foo:failed must both be
optional if both are used
To fix the error, we put question marks after the outputs:
foo:succeed? => bar # foo may succeed
foo:failed? => baz # foo may fail
Putting a question mark after a task output tells Cylc that it is optional (i.e. this output may or may not be generated when the task runs).
At Cylc 8 :finish
is equivalent to :succeed? | fail?
, so this:
foo:finish => bar # foo may either succeed or fail
Is equivalent to:
foo:succeed? | foo:failed? => bar # | means "or"
Which means that this workflow:
foo:finish => bar # foo MAY either succeed or fail
foo => baz # foo MUST succeed
Will fail validation:
$ cylc validate .
GraphParseError: Output foo:succeed can't be both required and optional
Because one of the foo:succeed
triggers has a question mark after it and the other doesn’t.
How To Fix Issues & Upgrade To Cylc 8
If you encounter this situation, there are two possible fixes.
-
If the
:finish
trigger was used by mistake, swap it for:succeed
.foo => bar # foo must succeed foo => baz # foo must succeed
-
If the
:finish
trigger was used purposefully, add question marks to allow the task to fail.foo:finished => bar # foo is permitted to fail foo? => baz # foo is permitted to fail
See graph branching for more information about those question mark symbols and how to direct Cylc to take different paths through the graph according to runtime events.