{"record":{"id":"0801d2276083d674","repo":"windmill-labs/windmill","slug":"result-was-none","errorCode":null,"errorMessage":"Result was none","messagePattern":"Result was none","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"python-client/wmill/wmill/client.py","lineNumber":430,"sourceCode":"            result_res = self.get(\n                f\"/w/{self.workspace}/jobs_u/completed/get_result_maybe/{job_id}\", True\n            ).json()\n\n            started = result_res[\"started\"]\n            completed = result_res[\"completed\"]\n            success = result_res[\"success\"]\n\n            if not started and verbose:\n                logger.info(f\"job {job_id} has not started yet\")\n\n            if cleanup and completed:\n                atexit.unregister(cancel_job)\n\n            if completed:\n                result = result_res[\"result\"]\n                if success:\n                    if result is None and assert_result_is_not_none:\n                        raise Exception(\"Result was none\")\n                    return result\n                else:\n                    error = result[\"error\"]\n                    raise Exception(f\"Job {job_id} was not successful: {str(error)}\")\n\n            if timeout and ((time.time() - start_time) > timeout):\n                msg = \"reached timeout\"\n                logger.warning(msg)\n                self.post(\n                    f\"/w/{self.workspace}/jobs_u/queue/cancel/{job_id}\",\n                    json={\"reason\": msg},\n                )\n                raise TimeoutError(msg)\n            if verbose:\n                logger.info(f\"sleeping 0.5 seconds for {job_id = }\")\n\n            time.sleep(0.5)\n","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/python-client/wmill/wmill/client.py#L412-L448","documentation":"wait_job polls a job until completion; when the job succeeds but its result is null and `assert_result_is_not_none=True`, the client raises 'Result was none'. It guards callers that require a meaningful return value from the script/flow.","triggerScenarios":"Calling wait_job(job_id, assert_result_is_not_none=True) on a job whose script finished successfully but returned None (script has no return/last expression, or explicitly returns None).","commonSituations":"Python script missing a final `return` statement so the job result is null; script intentionally side-effect-only but caller still asserts non-None; flow whose last step produces no output.","solutions":["Add a return value to the script (Python: `return {...}` as the last statement; TypeScript: return an object).","Set assert_result_is_not_none=False if a None result is acceptable.","Check the job's result in the UI/runs page to confirm what the script actually returned."],"exampleFix":"// before (script)\ndef main():\n    do_work()  # no return -> result None\n// after (script)\ndef main():\n    result = do_work()\n    return result\n// caller\nresult = client.wait_job(job_id, assert_result_is_not_none=True)","handlingStrategy":"try-catch","validationCode":"# before asserting, inspect the job result\ncompleted = client.get_job(job_id)\nif completed.get('success') and completed.get('result') is None:\n    logger.warning('job %s returned None; fix the script to return a value', job_id)","typeGuard":"def has_result(job_result) -> bool:\n    return job_result is not None","tryCatchPattern":"try:\n    result = client.wait_job(job_id, assert_result_is_not_none=True)\nexcept Exception as e:\n    if str(e) == 'Result was none':\n        result = default_value_or_retry()\n    else:\n        raise","preventionTips":["Ensure every waited script ends with an explicit return statement.","Only set assert_result_is_not_none=True for scripts guaranteed to return values.","Test scripts standalone in the UI to confirm their result before chaining them.","Side-effect-only scripts should not assert a non-None result."],"tags":["jobs","result","assertion","python"],"backgroundTag":"unexpected-null-result","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}