{"record":{"id":"15154a7162281d57","repo":"windmill-labs/windmill","slug":"result-is-none-for-job-id","errorCode":null,"errorMessage":"result is None for {job_id = }","messagePattern":"result is None for (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"python-client/wmill/wmill/client.py","lineNumber":576,"sourceCode":"\n    def get_result(\n        self,\n        job_id: str,\n        assert_result_is_not_none: bool = True,\n    ) -> Any:\n        \"\"\"Get the result of a completed job.\n\n        Args:\n            job_id: UUID of the completed job\n            assert_result_is_not_none: Raise exception if result is None\n\n        Returns:\n            Job result\n        \"\"\"\n        result = self.get(f\"/w/{self.workspace}/jobs_u/completed/get_result/{job_id}\")\n        result_text = result.text\n        if assert_result_is_not_none and result_text is None:\n            raise Exception(f\"result is None for {job_id = }\")\n        try:\n            return result.json()\n        except JSONDecodeError:\n            return result_text\n\n    def get_variable(self, path: str) -> str:\n        \"\"\"Get a variable value by path.\n\n        Args:\n            path: Variable path in Windmill\n\n        Returns:\n            Variable value as string\n        \"\"\"\n        path = parse_variable_syntax(path) or path\n        if self.mocked_api is not None:\n            variables = self.mocked_api[\"variables\"]\n            try:","sourceCodeStart":558,"sourceCodeEnd":594,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/python-client/wmill/wmill/client.py#L558-L594","documentation":"get_result() fetches a completed job's result; if assert_result_is_not_none=True and the raw response text is None it raises this error. Note the check is on result.text being None, which is rare — an empty body usually yields '' not None — so this mainly fires when the HTTP layer returns a null body object.","triggerScenarios":"Calling get_result(job_id, assert_result_is_not_none=True) on a job whose completed result payload is empty/None (e.g. script returned nothing).","commonSituations":"Side-effect-only scripts that return no value; querying results before the job produced output; asserting non-None on jobs known to return null.","solutions":["Have the script return an explicit value (e.g. `return {...}`).","Set assert_result_is_not_none=False when a None result is valid.","Check the job's result on the runs page to confirm what was stored."],"exampleFix":"// before\nres = client.get_result(job_id, assert_result_is_not_none=True)\n// after\nres = client.get_result(job_id, assert_result_is_not_none=False)\nif res is None:\n    res = {}","handlingStrategy":"validation","validationCode":"completed = client.get_job(job_id)\nif completed.get('result') is None and assert_non_none:\n    raise ValueError(f'job {job_id} has no result; do not assert')","typeGuard":"def result_present(res) -> bool:\n    return res is not None and res != ''","tryCatchPattern":"try:\n    res = client.get_result(job_id, assert_result_is_not_none=True)\nexcept Exception as e:\n    if 'result is None' in str(e):\n        res = None\n    else:\n        raise","preventionTips":["Ensure scripts return explicit values before querying their results.","Only enable assert_result_is_not_none when the script contract guarantees output.","Check the run's result in the UI to confirm stored output shape."],"tags":["jobs","result","python","windmill-client"],"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"}