Cannot unpack non-iterable NoneType object by API entity compute, params turn into None

PROBLEM

Hello!
I’m using the API entity compute from Viktor to control an automatic method. When I call the method, I give an dictionary as input for the params. If I print the input_dict before the statement to call the method, I get a full dictionary with logic input. However, when I print the params in the method of the Viktor Controller, I get an empty dictionary. Therefore I get the type error ‘cannot unpack non-iterable NoneType object’. It seems that the full dictonary turns into an empty one.
I checked my workspace, entity id and token from my app, but those are correct. Also, I used this code before with different input but the same kind of content, which worked by then. So why doesn’t it work anymore and what’s the solution to this problem?

INPUT

invoer_dict = dict(builder_type=params_eval.get(“builder_type”, 0).mean,
h_inw=params_eval.get(“h_inw”, 2.0).mean,
b_inw=params_eval.get(“b_inw”, 2.5).mean,
stootplaten=params_eval.get(“stootplaten”, “wel stootplaten”),
type_fundatie=params_eval.get(“type_fundatie”, “kespfundatie”),
bedding=params_eval.get(“bedding”, None),
k_waarde=params_eval.get(“k_waarde”, None),
h_g=params_eval.get(“h_g”, 0.0).mean,
d_w=params_eval.get(“d_w”, 0.25).mean,
d_d=params_eval.get(“d_d”, 0.25).mean,
d_v=params_eval.get(“d_v”, 0.25).mean,
b_k=params_eval.get(“b_k”, “C35/45”))

VIKTOR CALCULATION

api = vkt.api_v1.API(environment=“x”, token=“x”)

api.entity_compute(workspace_id=312,
entity_id=63838,
method_name=“automatic_download_scia_output_xml”,
params=invoer_dict, timeout=600)

APP

class Parametrization(vkt.Parametrization):
scia.downloads.automatic_output_xml = vkt.DownloadButton(“Automatic output xml [.xml]”, method=“automatic_download_scia_output_xml”)

class Duiker_Model(vkt.Controller):
def automatic_download_scia_output_xml(self, params, **kwargs):
print(kwargs)
print(params.toDict())
DUIKER_MODEL_1, DUIKER_MODEL_2 = adjust_duiker_model_w_mean(params)

entity_name: str = kwargs["entity_name"]
output_xml: str = self.scia_adjust_results(duiker_model_1=DUIKER_MODEL_1,
                                           duiker_model_2=DUIKER_MODEL_2)

with open("local/output.xml", "w+") as f:
    f.write(output_xml)

UITVOER TERMINAL:
INFO : Job (uid: 894471) received - EntityType: Duiker_Model - call: automatic_download_scia_output_xml
{‘entity_id’: x, ‘entity_name’: ‘Ontwerpvariant 0+1+2+3’, ‘event’: None, ‘workspace_id’: x}
{}
ERROR : Exception is raised
Traceback (most recent call last):
File “viktor_connector\connector.pyx”, line 334, in connector.Job.execute
File “viktor\core.pyx”, line 2079, in viktor.core._handle_job
File “viktor\core.pyx”, line 2016, in viktor.core._handle_job._handle_button
File “x”, line 54, in automatic_download_scia_output_xml
DUIKER_MODEL_1, DUIKER_MODEL_2 = adjust_duiker_model_w_mean(params)
TypeError: cannot unpack non-iterable NoneType object

Hi Milou,

First of all, welcome to the community forum.

Looking at your code, I noticed that the class Parametrization(vkt.Parametrization): does not include any of the input fields that correspond to the input parameters in your invoer_dict.

Is this the case? Could you try adding the input fields to the parametrization? e.g.

class Parametrization(vkt.Parametrization):
    scia.downloads.automatic_output_xml = vkt.DownloadButton(“Automatic output xml [.xml]”, method=“automatic_download_scia_output_xml”)
    scia.downloads.input_builder_type = vkt.OptionField(.., name="builder_type")  # you could even set visible=False if you don't want to show them in the interface
    scia.downloads.input_h_inw = vkt.NumberField(..., name="h_inw")
    ...

(note the name="h_inw" to align it with the keys in your invoer_dict, you can also decide to update the API call to api.entity_compute(..., params={"scia": {"downloads": invoer_dict}}, timeout=600)) instead.

Whenever a computation gets triggered through the API, we cross check and sanitize the provided params with the input fields defined in the parametrization. This ensures that the VIKTORController method always gets params as defined in the Parametrization. This allows us to use default values if they are provided in the input fields, and ignore obsolete values.

Please let me know if this helps your case!

Regards,

Hi!

First of all, thanks for replying!

I’m afraid I wasn’t totally clear about the context of my problem, because I’m not using input fields.
All the input I use is hard coded, given in the input dictionary. Therefore it isn’t the problem that the params don’t correspond with the input in the fields.

Somehow, the input that I recall in the API compute, isn’t deliverd in the methode I use, as I get an empty dictionary. It’s peculiar that this way of sending my input to the app has worked before, but not anymore, while the code hasn’t changed.

Please let me know if you can think of a solution.

Regards

Hi Milou,

We’ve recently recently fixed a few bugs where certain parameter values were missing when running a computation. This was included in the release of last week.

As I mentioned above, we now cross-check the provided params with the specification that is defined in the Parametrization (i.e. we validate the params against the Parametrization input fields). Any missing parameters will be added based on defaults and any ‘extra’ parameters (i.e. parameters that do no have a corresponding field in the Parametrization) will be excluded.

The easiest way to fix this for you, would be to add the input fields for these ‘extra’ parameters. You can do this by adding the following to the app that performs the xml creation:

class Parametrization(vkt.Parametrization):
     ...
    scia.downloads.automatic_output_xml = vkt.DownloadButton(“Automatic output xml [.xml]”, method=“automatic_download_scia_output_xml”)
    # Add the fields below
    scia.downloads.input_builder_type = vkt.TextField("builder_type", name="builder_type", visible=False)
    scia.downloads.input_h_inw = vkt.NumberField("h_inw", name="h_inw", visible=False)
    scia.downloads.input_b_inw = vkt.NumberField("b_inw", name="b_inw", visible=False)
    scia.downloads.input_stootplaten n= vkt.TextField("stootplaten", name="stootplaten", visible=False)
    scia.downloads.input_bedding = vkt.NumberField("bedding", name="bedding", visible=False)
    scia.downloads.input_k_waarde = vkt.NumberField("k_waarde", name="k_waarde", visible=False)
    scia.downloads.input_h_g = vkt.NumberField("h_g", name="h_g", visible=False)
    scia.downloads.input_d_w = vkt.NumberField("d_w", name="d_w", visible=False)
    scia.downloads.input_d_d = vkt.NumberField("d_d", name="d_d", visible=False)
    scia.downloads.input_d_v = vkt.NumberField("d_v", name="d_v", visible=False)
    scia.downloads.input_b_k = vkt.TextField("b_k", name="b_k", visible=False)

class Duiker_Model(vkt.Controller):
    parametrization = Parametrization

    def automatic_download_scia_output_xml(self, params, **kwargs):
          ...

I hope this clears things up. Please let me know if you have any questions.

Hi Kevin,

Thanks for explaining; I didn’t know Viktor was recently updated. With adding the missing parameters as input fields, Viktor indeed delivers the given params.

However, when I run the API entity_compute, I get a message ‘Reload triggered while processing job’. I’m using an optimalisation tool to generate different construction models. Therefore I call the automatic output.xml method from the app multiple times. It seems the code gets stuck on the error of reloading while Viktor is still working:

2025-06-17 10:02:39.152 INFO : External analysis not yet finished, waiting 1.0 seconds to retry…
2025-06-17 10:02:40.273 INFO : External analysis not yet finished, waiting 1.0 seconds to retry…
2025-06-17 10:02:41.393 INFO : External analysis not yet finished, waiting 1.0 seconds to retry…
2025-06-17 10:02:42.474 INFO : External analysis not yet finished, waiting 1.0 seconds to retry…
2025-06-17 10:02:43.571 INFO : External analysis not yet finished, waiting 1.0 seconds to retry…
2025-06-17 10:02:44.664 INFO : External analysis not yet finished, waiting 1.0 seconds to retry…
2025-06-17 10:02:45.748 INFO : External analysis not yet finished, waiting 1.0 seconds to retry…
2025-06-17 10:02:46.833 INFO : External analysis not yet finished, waiting 1.0 seconds to retry…
2025-06-17 10:02:47.928 INFO : External analysis not yet finished, waiting 1.0 seconds to retry…
2025-06-17 10:02:49.004 INFO : External analysis not yet finished, waiting 1.0 seconds to retry…
2025-06-17 10:02:50.115 INFO : External analysis not yet finished, waiting 1.0 seconds to retry…
2025-06-17 10:02:51.233 INFO : External analysis not yet finished, waiting 1.0 seconds to retry…
2025-06-17 10:02:52.365 INFO : External analysis not yet finished, waiting 1.0 seconds to retry…
2025-06-17 10:02:53.510 INFO : External analysis not yet finished, waiting 1.0 seconds to retry…
2025-06-17 10:02:54.743 INFO : External analysis not yet finished, waiting 1.0 seconds to retry…
2025-06-17 10:02:55.897 INFO : External analysis not yet finished, waiting 2.0 seconds to retry…
2025-06-17 10:02:57.983 INFO : External analysis not yet finished, waiting 2.0 seconds to retry…
2025-06-17 10:03:00.057 INFO : External analysis not yet finished, waiting 2.0 seconds to retry…
2025-06-17 10:03:02.138 INFO : External analysis not yet finished, waiting 2.0 seconds to retry…
2025-06-17 10:03:04.231 INFO : External analysis not yet finished, waiting 2.0 seconds to retry…
2025-06-17 10:03:06.326 INFO : External analysis not yet finished, waiting 3.0 seconds to retry…
2025-06-17 10:03:09.401 INFO : External analysis not yet finished, waiting 3.0 seconds to retry…
2025-06-17 10:03:12.619 INFO : External analysis not yet finished, waiting 3.0 seconds to retry…
2025-06-17 10:03:21.559 INFO : External analysis completed successfully, returning results
2025-06-17 10:03:21.615 INFO : Job (uid: 898315) completed in 50107ms
2025-06-17 10:03:21.666 INFO : Reload triggered while processing job. Reload after job finishes.
2025-06-17 10:03:21.850 INFO : Reloading app…

How can I fix this? I already tried to use time.sleep(), but that won’t fix the problem. Does this problem also relates to the new release of Viktor? Because I also didn’t have this issue before.

Regards,

Hi Milou,

I think that this part is causing the Reload triggered while processing job. Reload after job finishes. message:

output_xml: str = self.scia_adjust_results(duiker_model_1=DUIKER_MODEL_1,
                                           duiker_model_2=DUIKER_MODEL_2)

with open("local/output.xml", "w+") as f:
    f.write(output_xml)

The VIKTOR-cli watches your app directory for any file changes, if a change is spotted it tries to reload the app. In your case, a new file is added in your local folder in app directory, which is spotted by the VIKTOR-cli.

What is the reason that you write the xml file to disk?

I think that if you remove the:

with open("local/output.xml", "w+") as f:
    f.write(output_xml)

you will no longer see the Reload message (unless you also write other files to disk).

Kind regards,

Hi Kevin,

Thanks for replying quickly. Saving the file might indeed be the case of reloading the app (although I didn’t have this issue before with the same code).

However, I need the outpux_xml file for getting the internal forces.

Is there another option to fix this problem?

Regards,