ValueError: Error occurred validating port 'inputs.x': in WorkChain tutorial

Hi,

I am trying the quantum mobile 23.04.03 with WorkChain Tutorial on these pages
https://aiida.readthedocs.io/projects/aiida-core/en/latest/intro/tutorial.html
and
https://aiida.readthedocs.io/projects/aiida-core/en/latest/howto/write_workflows.html#how-to-write-workflows

The code is like following

"""Implementation of the MultiplyAddWorkChain for testing and demonstration purposes."""
from aiida.engine import ToContext, WorkChain, calcfunction, submit
from aiida.orm import AbstractCode, Int
from aiida.plugins.factories import CalculationFactory

ArithmeticAddCalculation = CalculationFactory('core.arithmetic.add')


@calcfunction
def multiply(x, y):
    return x * y


class MultiplyAddWorkChain(WorkChain):
    """WorkChain to multiply two numbers and add a third, for testing and demonstration purposes."""

    @classmethod
    def define(cls, spec):
        """Specify inputs and outputs."""
        super().define(spec)
        spec.input('x', valid_type=Int)
        spec.input('y', valid_type=Int)
        spec.input('z', valid_type=Int)
        spec.input('code', valid_type=AbstractCode)
        spec.outline(
            cls.multiply,
            cls.add,
            cls.validate_result,
            cls.result,
        )
        spec.output('result', valid_type=Int)
        spec.exit_code(400, 'ERROR_NEGATIVE_NUMBER', message='The result is a negative number.')

    def multiply(self):
        """Multiply two integers."""
        self.ctx.product = multiply(self.inputs.x, self.inputs.y)

    def add(self):
        """Add two numbers using the `ArithmeticAddCalculation` calculation job plugin."""
        inputs = {'x': self.ctx.product, 'y': self.inputs.z, 'code': self.inputs.code}
        future = self.submit(ArithmeticAddCalculation, **inputs)

        return ToContext(addition=future)

    def validate_result(self):
        """Make sure the result is not negative."""
        result = self.ctx.addition.outputs.sum

        if result.value < 0:
            return self.exit_codes.ERROR_NEGATIVE_NUMBER

    def result(self):
        """Add the result to the outputs."""
        self.out('result', self.ctx.addition.outputs.sum)

add_code = load_code(label='add@tutor')
inputs = {
    'multiply_add': {'x': Int(1), 'y': Int(2), 'z': Int(3), 'code': add_code}
}

workchain_node = submit(MultiplyAddWorkChain, **inputs)

and the error message is like this

$ verdi run work_chain.py 
Traceback (most recent call last):
  File "/home/max/.conda/envs/aiida/bin/verdi", line 10, in <module>
    sys.exit(verdi())
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/cmdline/utils/decorators.py", line 73, in wrapper
    return wrapped(*args, **kwargs)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/cmdline/commands/cmd_run.py", line 115, in run
    exec(compile(handle.read(), str(filepath), 'exec', dont_inherit=True), globals_dict)  # pylint: disable=exec-used
  File "work_chain.py", line 61, in <module>
    workchain_node = submit(MultiplyAddWorkChain, **inputs)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/engine/launch.py", line 103, in submit
    process_inited = instantiate_process(runner, process, **inputs)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/engine/utils.py", line 63, in instantiate_process
    process = process_class(runner=runner, inputs=inputs)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/base/state_machine.py", line 194, in __call__
    inst.transition_to(inst.create_initial_state())
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/base/state_machine.py", line 339, in transition_to
    self.transition_failed(initial_state_label, label, *sys.exc_info()[1:])
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/processes.py", line 1003, in transition_failed
    raise exception.with_traceback(trace)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/base/state_machine.py", line 324, in transition_to
    self._enter_next_state(new_state)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/base/state_machine.py", line 384, in _enter_next_state
    self._fire_state_event(StateEventHook.ENTERING_STATE, next_state)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/base/state_machine.py", line 300, in _fire_state_event
    callback(self, hook, state)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/processes.py", line 329, in <lambda>
    lambda _s, _h, state: self.on_entering(cast(process_states.State, state)),
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/processes.py", line 683, in on_entering
    call_with_super_check(self.on_create)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/base/utils.py", line 29, in call_with_super_check
    wrapped(*args, **kwargs)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/engine/processes/process.py", line 395, in on_create
    super().on_create()
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/base/utils.py", line 16, in wrapper
    wrapped(self, *args, **kwargs)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/processes.py", line 750, in on_create
    raise ValueError(result)
ValueError: Error occurred validating port 'inputs.x': required value was not provided for 'x'

I searched the old tutorial (Work chains — AiiDA Tutorials), but the run method (result = run(OutputInputWorkChain, x=Int(4) )) does not work either.

It seems the Calfunction Multiply cannot find inputs.x. I suppose the basic tutorial should be intuituive.
And the verdi status works well

$ verdi status
 ✔ version:     AiiDA v2.2.2
 ✔ config:      /home/max/.aiida
 ✔ profile:     generic
 ✔ storage:     Storage for 'generic' [open] @ postgresql://aiida:***@localhost:5432/aiidadb / DiskObjectStoreRepository: f5010831c906446994521daf1eac7c2e | /home/max/.aiida/repository/generic/container
 ✔ rabbitmq:    Connected to RabbitMQ v3.8.2 as amqp://guest:guest@127.0.0.1:5672?heartbeat=600
 ✔ daemon:      Daemon is running as PID 242291 since 2023-12-06 16:06:33
(aiida) max@qmobile:~/AiiDA_Tutorial/2021$ 

So, what is the problem…

Many thanks for your help!

Sincerely,
Dr. Guoyu Yang
Lecturer
Jimei Univ, School of Science, Digital Fujian Big Data Modeling and Intelligent Computing Institute
185 Yinjiang Rd.,
Jimei District, Xiamen,361021
Fujian, China
E-mail: 201961000100@jmu.edu.cn

The problem is with the structure of your inputs:

You have them nested in the multiply_add dictionary. If you then “explode” them in the submit call usign **inputs, you are really just calling

submit(MultiplyAddWorkChain, mutiply_add={'x': Int(1), 'y': Int(2), 'z': Int(3), 'code': add_code})

But the workchain doesn’t have a multiply_add input. The solution is simply to get rid of the multiply_add subnesting:

inputs = {'x': Int(1), 'y': Int(2), 'z': Int(3), 'code': add_code}
workchain_node = submit(MultiplyAddWorkChain, **inputs)

That should do it :+1:

Hi, sphuber,

Many thanks for your timely reply!

I have made the change as you suggested in the inputs. The programe can find the inputs.x now but it gives another AttrubuteError…
(I have done the
$ verdi daemon restart
Restarting the daemon… OK

As mentioned in FAQ)

the code is now

"""Implementation of the MultiplyAddWorkChain for testing and demonstration purposes."""
from aiida.engine import ToContext, WorkChain, calcfunction, submit
from aiida.orm import AbstractCode, Int
from aiida.plugins.factories import CalculationFactory

ArithmeticAddCalculation = CalculationFactory('core.arithmetic.add')


@calcfunction
def multiply(x, y):
    return x * y


class MultiplyAddWorkChain(WorkChain):
    """WorkChain to multiply two numbers and add a third, for testing and demonstration purposes."""

    @classmethod
    def define(cls, spec):
        """Specify inputs and outputs."""
        super().define(spec)
        spec.input('x', valid_type=Int)
        spec.input('y', valid_type=Int)
        spec.input('z', valid_type=Int)
        spec.input('code', valid_type=AbstractCode)
        spec.outline(
            cls.multiply,
            cls.add,
            cls.validate_result,
            cls.result,
        )
        spec.output('result', valid_type=Int)
        spec.exit_code(400, 'ERROR_NEGATIVE_NUMBER', message='The result is a negative number.')

    def multiply(self):
        """Multiply two integers."""
        self.ctx.product = multiply(self.inputs.x, self.inputs.y)

    def add(self):
        """Add two numbers using the `ArithmeticAddCalculation` calculation job plugin."""
        inputs = {'x': self.ctx.product, 'y': self.inputs.z, 'code': self.inputs.code}
        future = self.submit(ArithmeticAddCalculation, **inputs)

        return ToContext(addition=future)

    def validate_result(self):
        """Make sure the result is not negative."""
        result = self.ctx.addition.outputs.sum

        if result.value < 0:
            return self.exit_codes.ERROR_NEGATIVE_NUMBER

    def result(self):
        """Add the result to the outputs."""
        self.out('result', self.ctx.addition.outputs.sum)

add_code = load_code(label='add@tutor')
'''
inputs = {
    'multiply_add': {'x': Int(1), 'y': Int(2), 'z': Int(3), 'code': add_code}
}
'''

inputs = {'x': Int(1), 'y': Int(2), 'z': Int(3), 'code': add_code}
workchain_node = submit(MultiplyAddWorkChain, **inputs)

and the error message is now

$ verdi run work_chain.py 
12/07/2023 08:18:21 AM <271155> plumpy.processes: [ERROR] Exception trying to save checkpoint, this means you will not be able to restart in case of a crash until the next successful checkpoint.
Traceback (most recent call last):
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/engine/persistence.py", line 53, in load_object
    return getattr(module, name)
AttributeError: module '__main__' has no attribute 'MultiplyAddWorkChain'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/engine/persistence.py", line 86, in save_checkpoint
    bundle = plumpy.persistence.Bundle(process, plumpy.persistence.LoadSaveContext(loader=get_object_loader()))
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/persistence.py", line 47, in __init__
    self.update(savable.save(save_context))
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/persistence.py", line 507, in save
    Savable._set_class_name(out_state, loader.identify_object(self.__class__))
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/loaders.py", line 63, in identify_object
    self.load_object(identifier)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/engine/persistence.py", line 55, in load_object
    raise ImportError(f"object '{name}' from identifier '{identifier}' could not be loaded")
ImportError: object 'MultiplyAddWorkChain' from identifier '__main__:MultiplyAddWorkChain' could not be loaded

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/engine/processes/process.py", line 261, in _save_checkpoint
    self.runner.persister.save_checkpoint(self)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/engine/persistence.py", line 89, in save_checkpoint
    raise PersistenceError(f"Failed to create a bundle for '{process}': {traceback.format_exc()}")
plumpy.exceptions.PersistenceError: Failed to create a bundle for '<MultiplyAddWorkChain> (ProcessState.CREATED)': Traceback (most recent call last):
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/engine/persistence.py", line 53, in load_object
    return getattr(module, name)
AttributeError: module '__main__' has no attribute 'MultiplyAddWorkChain'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/engine/persistence.py", line 86, in save_checkpoint
    bundle = plumpy.persistence.Bundle(process, plumpy.persistence.LoadSaveContext(loader=get_object_loader()))
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/persistence.py", line 47, in __init__
    self.update(savable.save(save_context))
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/persistence.py", line 507, in save
    Savable._set_class_name(out_state, loader.identify_object(self.__class__))
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/loaders.py", line 63, in identify_object
    self.load_object(identifier)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/engine/persistence.py", line 55, in load_object
    raise ImportError(f"object '{name}' from identifier '{identifier}' could not be loaded")
ImportError: object 'MultiplyAddWorkChain' from identifier '__main__:MultiplyAddWorkChain' could not be loaded

Traceback (most recent call last):
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/engine/persistence.py", line 53, in load_object
    return getattr(module, name)
AttributeError: module '__main__' has no attribute 'MultiplyAddWorkChain'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/engine/persistence.py", line 86, in save_checkpoint
    bundle = plumpy.persistence.Bundle(process, plumpy.persistence.LoadSaveContext(loader=get_object_loader()))
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/persistence.py", line 47, in __init__
    self.update(savable.save(save_context))
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/persistence.py", line 507, in save
    Savable._set_class_name(out_state, loader.identify_object(self.__class__))
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/loaders.py", line 63, in identify_object
    self.load_object(identifier)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/engine/persistence.py", line 55, in load_object
    raise ImportError(f"object '{name}' from identifier '{identifier}' could not be loaded")
ImportError: object 'MultiplyAddWorkChain' from identifier '__main__:MultiplyAddWorkChain' could not be loaded

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/max/.conda/envs/aiida/bin/verdi", line 10, in <module>
    sys.exit(verdi())
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/cmdline/utils/decorators.py", line 73, in wrapper
    return wrapped(*args, **kwargs)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/cmdline/commands/cmd_run.py", line 115, in run
    exec(compile(handle.read(), str(filepath), 'exec', dont_inherit=True), globals_dict)  # pylint: disable=exec-used
  File "work_chain.py", line 64, in <module>
    workchain_node = submit(MultiplyAddWorkChain, **inputs)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/engine/launch.py", line 115, in submit
    runner.persister.save_checkpoint(process_inited)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/engine/persistence.py", line 89, in save_checkpoint
    raise PersistenceError(f"Failed to create a bundle for '{process}': {traceback.format_exc()}")
plumpy.exceptions.PersistenceError: Failed to create a bundle for '<MultiplyAddWorkChain> (ProcessState.CREATED)': Traceback (most recent call last):
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/engine/persistence.py", line 53, in load_object
    return getattr(module, name)
AttributeError: module '__main__' has no attribute 'MultiplyAddWorkChain'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/engine/persistence.py", line 86, in save_checkpoint
    bundle = plumpy.persistence.Bundle(process, plumpy.persistence.LoadSaveContext(loader=get_object_loader()))
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/persistence.py", line 47, in __init__
    self.update(savable.save(save_context))
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/persistence.py", line 507, in save
    Savable._set_class_name(out_state, loader.identify_object(self.__class__))
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/plumpy/loaders.py", line 63, in identify_object
    self.load_object(identifier)
  File "/home/max/.conda/envs/aiida/lib/python3.9/site-packages/aiida/engine/persistence.py", line 55, in load_object
    raise ImportError(f"object '{name}' from identifier '{identifier}' could not be loaded")
ImportError: object 'MultiplyAddWorkChain' from identifier '__main__:MultiplyAddWorkChain' could not be loaded


Sincerely,
Dr. Guoyu Yang
Lecturer
Jimei Univ, School of Science, Digital Fujian Big Data Modeling and Intelligent Computing Institute
185 Yinjiang Rd.,
Jimei District, Xiamen,361021
Fujian, China
E-mail: 201961000100@jmu.edu.cn

The problem is that you are submittting the job to the daemon. This means the daemon needs to be able to import the workchain, MultiplyAddWorkChain in your case. However, that is defined in the run script, and that is not an importable package.

See this page in the docs why and this FAQ.

The most simple solution is to change this line in your script:

workchain_node = submit(MultiplyAddWorkChain, **inputs)

to

results, workchain_node = run.get_node(MultiplyAddWorkChain, **inputs)

This will run the workchain in the script itself, and then it doesn’t need to be imported, because it is already defined there.

If you really want to submit it, you have to make the workchain to a package that can be imported by the daemon, just like any other Python package.