Lightning-AI/pytorch-lightning · error · MisconfigurationException

Schedule should be a callable. Found: {schedule}

Error message

Schedule should be a callable. Found: {schedule}

What it means

When PyTorchProfiler is created with a schedule in profiler_kwargs (e.g. via Trainer(profiler=PyTorchProfiler(...)) with schedule), _init_kineto requires it to be a callable — normally the result of torch.profiler.schedule(...). A non-callable (e.g. a string or dict) raises MisconfigurationException.

Source

Thrown at src/lightning/pytorch/profilers/pytorch.py:342

                raise KeyError(
                    f"Found invalid table_kwargs key: {key}. This is already a positional argument of the Profiler."
                )
            valid_table_keys = set(inspect.signature(EventList.table).parameters.keys()) - {
                "self",
                "sort_by",
                "row_limit",
            }
            if key not in valid_table_keys:
                raise KeyError(f"Found invalid table_kwargs key: {key}. Should be within {valid_table_keys}.")

    def _init_kineto(self, profiler_kwargs: Any) -> None:
        has_schedule = "schedule" in profiler_kwargs
        self._has_on_trace_ready = "on_trace_ready" in profiler_kwargs

        schedule = profiler_kwargs.get("schedule", None)
        if schedule is not None:
            if not callable(schedule):
                raise MisconfigurationException(f"Schedule should be a callable. Found: {schedule}")
            action = schedule(0)
            if not isinstance(action, ProfilerAction):
                raise MisconfigurationException(
                    f"Schedule should return a `torch.profiler.ProfilerAction`. Found: {action}"
                )
        self._default_schedule()
        schedule = schedule if has_schedule else self._default_schedule()
        self._schedule = ScheduleWrapper(schedule) if schedule is not None else schedule
        self._profiler_kwargs["schedule"] = self._schedule

        activities = profiler_kwargs.get("activities", None)
        self._profiler_kwargs["activities"] = activities or self._default_activities()
        self._export_to_flame_graph = profiler_kwargs.get("export_to_flame_graph", False)
        self._metric = profiler_kwargs.get("metric", "self_cpu_time_total")
        with_stack = profiler_kwargs.get("with_stack", False) or self._export_to_flame_graph
        self._profiler_kwargs["with_stack"] = with_stack

    @property

View on GitHub (pinned to 9fed5c27d2)

Solutions

  1. Create the schedule with torch.profiler.schedule(wait=..., warmup=..., active=..., repeat=...) and pass that object
  2. If loading config, convert the parsed settings into a call: functools.partial(torch.profiler.schedule, **cfg)
  3. Omit schedule entirely if you don't need step-based profiling

Example fix

# before
profiler = PyTorchProfiler(profiler_kwargs={"schedule": {"wait": 1, "warmup": 1, "active": 3}})

# after
profiler = PyTorchProfiler(
    schedule=torch.profiler.schedule(wait=1, warmup=1, active=3, repeat=1)
)
Defensive patterns

Strategy: type-guard

Validate before calling

if schedule is not None:
    assert callable(schedule), f"schedule must be callable, got {type(schedule)}"

Type guard

def is_valid_schedule(s) -> bool:
    import inspect
    from torch.profiler import ProfilerAction
    if not callable(s):
        return False
    try:
        return isinstance(s(0), ProfilerAction)
    except Exception:
        return False

Try / catch

try:
    profiler = PyTorchProfiler(schedule=schedule)
except MisconfigurationException as e:
    profiler = PyTorchProfiler(schedule=torch.profiler.schedule(wait=1, warmup=1, active=3))

Prevention

When it happens

Trigger: Passing profiler_kwargs={'schedule': torch.profiler.schedule(wait=1, warmup=1, active=3)} is correct; passing {'schedule': 'wait=1,warmup=1'} or a dict/config object instead of the callable produced by torch.profiler.schedule() triggers it.

Common situations: Loading profiler config from YAML/JSON and passing the raw string/dict instead of constructing a schedule; forgetting the parentheses so a function reference vs. its result confusion arises; wrapping schedule in a non-callable wrapper.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28). Data as JSON: /api/errors/a0140e0a2ada7151. Report an issue: GitHub.