Debugging work chains#

In this section, we highlight a series of common issues you may encounter when writing work chains with AiiDA, and explain how to debug them.

I can’t import my work chain!

When trying to import a work chain in the IPython terminal, you get a No module named ... error message:

In [1]: from addcalcjobworkchain import AddCalcjobWorkChain
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-1-03fcc3f6b521> in <module>
----> 1 from addcalcjobworkchain import AddCalcjobWorkChain

ModuleNotFoundError: No module named 'addcalcjobworkchain'

My work chain is stuck in the Created state!

You’ve submitted your work chain, but no matter how long you wait, the process stays in the Created state:

$ verdi process list
  PK  Created    Process label         Process State    Process status
----  ---------  --------------------  ---------------  ----------------
2745  7s ago     OutputInputWorkChain  ⏹ Created

Total results: 1

Info: last time an entry changed state: 7s ago (at 01:36:44 on 2021-07-07)
Warning: the daemon is not running

The changes I made in my work chain have no effect!

You’ve just added an extra step, fixed a bug, updated an input, etc. in your work chain, but when you resubmit the work chain for testing, nothing seems to have changed.

My work chain is Finished, but the exit code is not zero!

Your work chain has completed and is in a Finished state, but the exit code is different from zero:

$ verdi process list -a -p 1
  PK  Created    Process label                 Process State     Process status
----  ---------  ----------------------------  ----------------  ----------------
 575  8D ago     PwRelaxWorkChain              ⏹ Finished [401]
 578  8D ago     PwBaseWorkChain               ⏹ Finished [300]
 579  8D ago     create_kpoints_from_distance  ⏹ Finished [0]
 583  8D ago     PwCalculation                 ⏹ Finished [305]

Total results: 4

Info: last time an entry changed state: 2m ago (at 01:36:44 on 2021-07-07)

My work chain is in the Excepted state!

You submitted your work chain, but don’t see it when executing verdi process list. When you check for all processes, you see it’s in an Excepted state:

$ verdi process list -a -p 1
  PK  Created    Process label         Process State    Process status
----  ---------  --------------------  ---------------  ----------------
2745  2m ago     OutputInputWorkChain  ⨯ Excepted

Total results: 1

Info: last time an entry changed state: 2m ago (at 01:36:44 on 2021-07-07)

Wrong data type for the input#

Here, we demonstrate what happens if you input a wrong data type to a work chain in the running or submission process. For that, we consider the OutputInputWorkChain written in the Work chain section.

You can download the script here.

After downloading the work chain script to your computer where you are running AiiDA, navigate to the folder where you have saved the script and run in the verdi shell

In [1]: from aiida.engine import run
In [2]: from my_first_workchain_1_output_input import OutputInputWorkChain
In [3]: result = run(OutputInputWorkChain, x=4)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-5-118afb74821c> in <module>
----> 1 result = run(OutputInputWorkChain, x=4)
...
ValueError: Error occurred validating port 'inputs.x': value 'x' is not of the right type. Got '<class 'int'>', expected '<class 'aiida.orm.nodes.data.int.Int'>'

In the third command line, we tried to run the OutputInputWorkChain passing a Python integer as the input. However, the work chain is expecting an AiiDA integer data type, which can be created using the Int() class. See the declaration of the input of the OutputInputWorkChain:

        spec.input("x", valid_type=Int)

When writing a work chain, specifying which type of data is expected is the first step of creating robust work chains.

The problem can be corrected as in the following example:

In [1]: from aiida.engine import run
In [2]: from my_first_workchain_1_output_input import OutputInputWorkChain
In [3]: result = run(OutputInputWorkChain, x=Int(4))

Passing wrong data type to the output#

Modify the OutputWorkChain declaring the output label workchain_result as of the type Float:

from aiida.orm import Int, Float
from aiida.engine import WorkChain


class OutputInputWorkChain(WorkChain):
    """Toy WorkChain that simply passes the input as an output."""

    @classmethod
    def define(cls, spec):
        """Specify inputs, outputs, and the workchain outline."""
        super().define(spec)

        spec.input("x", valid_type=Int)
        spec.outline(cls.result)
        spec.output("workchain_result", valid_type=Float)

    def result(self):
        """Pass the input as an output."""

        # Declaring the output
        self.out("workchain_result", self.inputs.x)

The script will then try to output an Int where a Float is expected instead. Run the following in the verdi shell to see what error this will generate:

In [1]: from aiida.engine import run
In [2]: from my_first_workchain_1_output_input import OutputInputWorkChain
In [3]: result = run(OutputInputWorkChain, x=Int(4) )
07/05/2021 12:52:48 PM <25305> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [382|OutputInputWorkChain|on_except]: Traceback (most recent call last):
  File "/home/fdossantos/venv/aiida_git/lib/python3.8/site-packages/plumpy/process_states.py", line 229, in execute
    result = self.run_fn(*self.args, **self.kwargs)
  File "/home/fdossantos/venv/aiida_git/lib/python3.8/site-packages/aiida/engine/processes/workchains/workchain.py", line 194, in run
    return self._do_step()
  File "/home/fdossantos/venv/aiida_git/lib/python3.8/site-packages/aiida/engine/processes/workchains/workchain.py", line 211, in _do_step
    finished, stepper_result = self._stepper.step()
  File "/home/fdossantos/venv/aiida_git/lib/python3.8/site-packages/plumpy/workchains.py", line 250, in step
    return True, self._fn(self._workchain)
  File "/home/fdossantos/codes/aiida-tutorials/docs/sections/workflows/include/code/debugging/my_first_workchain_2_wrong_output.py", line 21, in result
    self.out("workchain_result", self.inputs.x)
  File "/home/fdossantos/venv/aiida_git/lib/python3.8/site-packages/aiida/engine/processes/process.py", line 354, in out
    return super().out(output_port, value)
  File "/home/fdossantos/venv/aiida_git/lib/python3.8/site-packages/plumpy/processes.py", line 79, in func_wrapper
    return func(self, *args, **kwargs)
  File "/home/fdossantos/venv/aiida_git/lib/python3.8/site-packages/plumpy/processes.py", line 1254, in out
    raise ValueError(msg)
ValueError: Error validating output 'uuid: 3fb97fdd-5b3f-4742-9ff8-aa604c91f055 (pk: 381) value: 4' for port 'workchain_result': value 'workchain_result' is not of the right type. Got '<class 'aiida.orm.nodes.data.int.Int'>', expected '<class 'aiida.orm.nodes.data.float.Float'>'

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-3-2c36ef047bf6> in <module>
----> 1 result = run(OutputInputWorkChain, x=Int(4) )
...

Of course, to correct this problem you have to make sure that you declared the right data types for the inputs and outputs, and that your work chain passes the right data nodes to the outputs. Declaring the data type of the output is another good-practice towards robust work chains.

Wrong output label#

Now, remove the modifications of the previous section as to obtain the original OutputInputWorkChain. Next, we will mimic a mistake when passing the output. Alter your script file to match the example below:

from aiida.orm import Int
from aiida.engine import WorkChain


class OutputInputWorkChain(WorkChain):
    """Toy WorkChain that simply passes the input as an output."""

    @classmethod
    def define(cls, spec):
        """Specify inputs, outputs, and the workchain outline."""
        super().define(spec)

        spec.input("x", valid_type=Int)
        spec.outline(cls.result)
        spec.output("workchain_result", valid_type=Int)

    def result(self):
        """Pass the input as an output."""

        # Declaring the output
        self.out("workchain_output", self.inputs.x)

Note that in the define method, we specified an output labelled workchain_result. In the result step, the work chain is trying to record an output labelled workchain_output, which was not declared. If we try to run the work chain, we get the following error:

In [1]: from aiida.engine import run
In [2]: from my_first_workchain_1_output_input import OutputInputWorkChain
In [3]: result = run(OutputInputWorkChain, x=Int(4) )
07/05/2021 01:02:24 PM <26497> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [384|OutputInputWorkChain|on_except]: Traceback (most recent call last):
  File "/home/fdossantos/venv/aiida_git/lib/python3.8/site-packages/plumpy/process_states.py", line 229, in execute
    result = self.run_fn(*self.args, **self.kwargs)
  File "/home/fdossantos/venv/aiida_git/lib/python3.8/site-packages/aiida/engine/processes/workchains/workchain.py", line 194, in run
    return self._do_step()
  File "/home/fdossantos/venv/aiida_git/lib/python3.8/site-packages/aiida/engine/processes/workchains/workchain.py", line 211, in _do_step
    finished, stepper_result = self._stepper.step()
  File "/home/fdossantos/venv/aiida_git/lib/python3.8/site-packages/plumpy/workchains.py", line 250, in step
    return True, self._fn(self._workchain)
  File "/home/fdossantos/codes/aiida-tutorials/docs/sections/workflows/include/code/debugging/my_first_workchain_3_wrong_label.py", line 21, in result
    self.out("workchain_output", self.inputs.x)
  File "/home/fdossantos/venv/aiida_git/lib/python3.8/site-packages/aiida/engine/processes/process.py", line 354, in out
    return super().out(output_port, value)
  File "/home/fdossantos/venv/aiida_git/lib/python3.8/site-packages/plumpy/processes.py", line 79, in func_wrapper
    return func(self, *args, **kwargs)
  File "/home/fdossantos/venv/aiida_git/lib/python3.8/site-packages/plumpy/processes.py", line 1254, in out
    raise ValueError(msg)
ValueError: Error validating output 'uuid: 584c88c4-bfb5-465f-a4d6-d455ce4e1f73 (pk: 383) value: 4' for port 'outputs': Unexpected ports {'workchain_output': <Int: uuid: 584c88c4-bfb5-465f-a4d6-d455ce4e1f73 (pk: 383) value: 4>}, for a non dynamic namespace
...

The error message explains that the work chain received an output called workchain_output, which was unexpected, since it was not declared in the spec. It is possible to activate a dynamic namespace where you don’t need to declare the outputs in the define() method. However, this feature is to be avoided unless you have a very good reason for doing so.