{"record":{"id":"5c90b93894c06263","repo":"windmill-labs/windmill","slug":"job-job-id-was-not-successful-str-error","errorCode":null,"errorMessage":"Job {job_id} was not successful: {str(error)}","messagePattern":"Job (.+?) was not successful: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"python-client/wmill/wmill/client.py","lineNumber":434,"sourceCode":"            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\n    def cancel_job(self, job_id: str, reason: str = None) -> str:\n        \"\"\"Cancel a specific job by ID.\n\n        Args:","sourceCodeStart":416,"sourceCodeEnd":452,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/python-client/wmill/wmill/client.py#L416-L452","documentation":"When a waited job completes unsuccessfully (status failure), wait_job extracts result['error'] and raises 'Job {job_id} was not successful: {error}'. This surfaces the script's own runtime failure captured by the Windmill server.","triggerScenarios":"wait_job() on a job whose script/flow raised an unhandled exception, exited non-zero, was canceled, or failed a step inside a flow; job reached failure state while the client was polling.","commonSituations":"Script bug (uncaught exception in the executed code); missing dependency in the script environment; failure of a resource/credential lookup at runtime; a downstream flow step failing.","solutions":["Read the embedded error text and open the job run in the Windmill UI (runs page) for the full stack trace.","Fix the underlying script error indicated in the message (imports, arguments, resource access).","Wrap wait_job in try/except if the caller should continue when the job fails.","Optionally set allowed_failure on the script/step so Windmill records success despite the error."],"exampleFix":"// before\nresult = client.wait_job(job_id)  # raises on failure\n// after\ntry:\n    result = client.wait_job(job_id)\nexcept Exception as e:\n    logger.error(f'job failed: {e}')\n    handle_failure(e)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    result = client.wait_job(job_id)\nexcept Exception as e:\n    if str(e).startswith('Job ') and 'was not successful' in str(e):\n        job_id = str(e).split()[1]\n        details = client.get_job(job_id)\n        logger.error('job failed: %s — see %s', e, details.get('logs'))\n    else:\n        raise","preventionTips":["Test the script in isolation in the Windmill UI before orchestrating it from Python.","Check job logs on the runs page for the underlying stack trace.","Use allowed_failure on optional steps so expected errors don't fail the job.","Pin script dependencies to avoid environment drift causing runtime failures."],"tags":["jobs","failure","python","windmill-client"],"backgroundTag":"job-execution-failed","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"}