{"record":{"id":"b8b90d11f95186fb","repo":"Lightning-AI/pytorch-lightning","slug":"schedule-should-return-a-torch-profiler-profilera","errorCode":null,"errorMessage":"Schedule should return a `torch.profiler.ProfilerAction`. Found: {action}","messagePattern":"Schedule should return a `torch\\.profiler\\.ProfilerAction`\\. Found: (.+?)","errorType":"exception","errorClass":"MisconfigurationException","httpStatus":null,"severity":"error","filePath":"src/lightning/pytorch/profilers/pytorch.py","lineNumber":345,"sourceCode":"            valid_table_keys = set(inspect.signature(EventList.table).parameters.keys()) - {\n                \"self\",\n                \"sort_by\",\n                \"row_limit\",\n            }\n            if key not in valid_table_keys:\n                raise KeyError(f\"Found invalid table_kwargs key: {key}. Should be within {valid_table_keys}.\")\n\n    def _init_kineto(self, profiler_kwargs: Any) -> None:\n        has_schedule = \"schedule\" in profiler_kwargs\n        self._has_on_trace_ready = \"on_trace_ready\" in profiler_kwargs\n\n        schedule = profiler_kwargs.get(\"schedule\", None)\n        if schedule is not None:\n            if not callable(schedule):\n                raise MisconfigurationException(f\"Schedule should be a callable. Found: {schedule}\")\n            action = schedule(0)\n            if not isinstance(action, ProfilerAction):\n                raise MisconfigurationException(\n                    f\"Schedule should return a `torch.profiler.ProfilerAction`. Found: {action}\"\n                )\n        self._default_schedule()\n        schedule = schedule if has_schedule else self._default_schedule()\n        self._schedule = ScheduleWrapper(schedule) if schedule is not None else schedule\n        self._profiler_kwargs[\"schedule\"] = self._schedule\n\n        activities = profiler_kwargs.get(\"activities\", None)\n        self._profiler_kwargs[\"activities\"] = activities or self._default_activities()\n        self._export_to_flame_graph = profiler_kwargs.get(\"export_to_flame_graph\", False)\n        self._metric = profiler_kwargs.get(\"metric\", \"self_cpu_time_total\")\n        with_stack = profiler_kwargs.get(\"with_stack\", False) or self._export_to_flame_graph\n        self._profiler_kwargs[\"with_stack\"] = with_stack\n\n    @property\n    def _total_steps(self) -> Union[int, float]:\n        assert self._schedule is not None\n        assert self._lightning_module is not None","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/pytorch/profilers/pytorch.py#L327-L363","documentation":"_init_kineto probes the user schedule by calling schedule(0) and requires the return value to be a torch.profiler.ProfilerAction enum member. Lightning's ScheduleWrapper relies on ProfilerAction transitions, so a custom callable returning something else (None, string, int) fails validation immediately.","triggerScenarios":"Passing a hand-written schedule callable such as lambda step: None or a function returning a string/int instead of torch.profiler.ProfilerAction (e.g. ProfilerAction.WARMUP vs 'WARMUP').","commonSituations":"Writing a custom schedule without importing torch.profiler.ProfilerAction; returning the enum's name string; early-returning None in one branch of a conditional custom schedule.","solutions":["Import from torch.profiler import ProfilerAction and return ProfilerAction members (NONE, WARMUP, RECORD, RECORD_AND_SAVE) for every step input","Handle all branches of your callable so it never returns None","Prefer composing torch.profiler.schedule() rather than writing a custom callable"],"exampleFix":"# before\nprofiler = PyTorchProfiler(schedule=lambda step: \"WARMUP\" if step < 3 else \"RECORD\")  # invalid\n\n# after\nfrom torch.profiler import ProfilerAction\nprofiler = PyTorchProfiler(\n    schedule=lambda step: ProfilerAction.WARMUP if step < 3 else ProfilerAction.RECORD_AND_SAVE\n)","handlingStrategy":"type-guard","validationCode":"from torch.profiler import ProfilerAction\nassert schedule(0) is not None and isinstance(schedule(0), ProfilerAction)","typeGuard":"def returns_profiler_action(schedule) -> bool:\n    from torch.profiler import ProfilerAction\n    try:\n        return isinstance(schedule(0), ProfilerAction)\n    except Exception:\n        return False","tryCatchPattern":null,"preventionTips":["Import ProfilerAction and return enum members in every branch of custom schedules","Test custom schedules with schedule(0) before passing to the profiler","Prefer composing torch.profiler.schedule over custom callables"],"tags":["profiler","schedule","type-error","pytorch"],"backgroundTag":"invalid-return-type","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}