{"record":{"id":"4d141fdc3c9f35a6","repo":"windmill-labs/windmill","slug":"main-override-function-is-missing","errorCode":null,"errorMessage":"{main_override} function is missing","messagePattern":"(.+?) function is missing","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/windmill-worker/src/python_executor.rs","lineNumber":967,"sourceCode":"_u=re.compile(r'\\\\\\\\|\\\\u0000')\n_us=lambda m:' null ' if m.group(0)[1]=='u' else m.group(0)\n_r=lambda m,s='':(_u.sub(_us,s) if '\\\\u0000' in s else s) if (s:=m.group(0))[0]=='\"' else ' null '\nreplace_invalid_fields=re.compile(r'\"(?:\\\\.|[^\"\\\\])*\"|\\bNaN\\b|-?Infinity')\n_fix=lambda s:s if 'Infinity' not in s and 'NaN' not in s and '\\\\u0000' not in s else re.sub(replace_invalid_fields,_r,s)\n\nresult_json = os.path.join(os.path.abspath(os.path.dirname(__file__)), \"result.json\")\n\ndef res_to_json(res, typ):\n{res_to_json_body}\n\ntry:\n    {preprocessor}\n    {spread}\n    for k, v in list(args.items()):\n        if v == '<function call>':\n            del args[k]\n    if inner_script.{main_override} is None or not callable(inner_script.{main_override}):\n        raise ValueError(\"{main_override} function is missing\")\n    res = inner_script.{main_override}(**args)\n    typ = type(res)\n    if hasattr(res, '__iter__') and not isinstance(res, (str, dict, list, bytes, tuple, set, frozenset, range, memoryview, bytearray)) and typ.__name__ != 'DataFrame':\n        for chunk in res:\n            print(\"WM_STREAM: \" + chunk.replace('\\n', '\\\\n'))\n        res = None\n    res_json = res_to_json(res, typ)\n    with open(result_json, 'w') as f:\n        f.write(res_json)\nexcept BaseException as e:\n    exc_type, exc_value, exc_traceback = sys.exc_info()\n    tb = traceback.format_tb(exc_traceback)\n    with open(result_json, 'w') as f:\n        err = {{ \"message\": str(e), \"name\": e.__class__.__name__, \"stack\": '\\n'.join(tb[1:]) }}\n        extra = e.__dict__\n        if extra and len(extra) > 0:\n            err['extra'] = extra\n        flow_node_id = os.environ.get('WM_FLOW_STEP_ID')","sourceCodeStart":949,"sourceCodeEnd":985,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/windmill-worker/src/python_executor.rs#L949-L985","documentation":"Raised inside the Python wrapper generated by handle_python_job when the script does not define the required entry function (the template's {main_override} is the expected function name, normally `main`). Windmill invokes scripts via main(**args); with no such callable there is nothing to run, so the injected try-block fails the job.","triggerScenarios":"Thrown at backend/windmill-worker/src/python_executor.rs:967 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Define a function named `main` whose parameters match the script's declared args","Rename the entry function to `main` (or align the configured override with its actual name)","Check the code actually reached the definition — it may sit behind an early return or condition"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}