microsoft/qlib · error · ValueError

The fetched task must be `STATUS_WAITING` or `STATUS_PART_DO

Error message

The fetched task must be `STATUS_WAITING` or `STATUS_PART_DONE`!

What it means

Raised in qlib.workflow.task.manage.run_task when the fetched task's trigger status is neither TaskManager.STATUS_WAITING nor STATUS_PART_DONE. The loop only knows how to build train parameters from task['def'] (waiting) or task['res'] (part done); any other status reaching the branch is a programming/config error.

Source

Thrown at qlib/workflow/task/manage.py:542

        the params for `task_func`
    """
    tm = TaskManager(task_pool)

    ever_run = False

    while True:
        with tm.safe_fetch_task(status=before_status, query=query) as task:
            if task is None:
                break
            get_module_logger("run_task").info(task["def"])
            # when fetching `WAITING` task, use task["def"] to train
            if before_status == TaskManager.STATUS_WAITING:
                param = task["def"]
            # when fetching `PART_DONE` task, use task["res"] to train because the middle result has been saved to task["res"]
            elif before_status == TaskManager.STATUS_PART_DONE:
                param = task["res"]
            else:
                raise ValueError("The fetched task must be `STATUS_WAITING` or `STATUS_PART_DONE`!")
            if force_release:
                with concurrent.futures.ProcessPoolExecutor(max_workers=1) as executor:
                    res = executor.submit(task_func, param, **kwargs).result()
            else:
                res = task_func(param, **kwargs)
            tm.commit_task_res(task, res, status=after_status)
            ever_run = True

    return ever_run


if __name__ == "__main__":
    # This is for using it in cmd
    # E.g. : `python -m qlib.workflow.task.manage list`
    auto_init()
    fire.Fire(TaskManager)

View on GitHub (pinned to 79633dd950)

Solutions

  1. Pass before_status=TaskManager.STATUS_WAITING (default) or TaskManager.STATUS_PART_DONE to run_task; these are the only supported fetch states.
  2. If you need a custom lifecycle, wrap task_func so it saves intermediate results and re-fetch as PART_DONE rather than inventing new before_status values.
  3. Ensure no other process flips fetched tasks to a different status mid-run (use safe_fetch_task locking semantics).

Example fix

// before
run_task(task_func, before_status=TaskManager.STATUS_DONE)

// after
run_task(task_func, before_status=TaskManager.STATUS_WAITING)
Defensive patterns

Strategy: validation

Validate before calling

from qlib.workflow.task.manage import TaskManager
assert before_status in (TaskManager.STATUS_WAITING, TaskManager.STATUS_PART_DONE), f"unsupported before_status: {before_status}"

Prevention

When it happens

Trigger: Calling run_task(task_func, before_status=TaskManager.STATUS_DONE) or any status other than WAITING/PART_DONE — the while loop fetches a task with that status and then hits the else branch immediately.

Common situations: Custom task lifecycle code that passes STATUS_RUNNING/STATUS_DONE as before_status; tasks whose status was mutated concurrently by another worker between fetch and dispatch; copy-paste of the run_task loop with a new status value without extending the branch.

Related errors


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/634cf8bc833c4938. Report an issue: GitHub.