vllm-project/vllm · error · RuntimeError

Unsupported task: {pooling_task!r} Supported tasks: {support

Error message

Unsupported task: {pooling_task!r} Supported tasks: {supported_tasks}

What it means

get_pooling_task resolves which pooling task to run; when the user explicitly set a task in --pooling-task but that task is not among the tasks the model supports, it raises RuntimeError listing the supported set. This is a task/model compatibility failure, not a parsing error.

Source

Thrown at vllm/config/model.py:1736

                str(diff_sampling_param),
                scope="local",
            )

        return diff_sampling_param

    def get_pooling_task(
        self, supported_tasks: tuple[SupportedTask, ...]
    ) -> PoolingTask | None:
        if self.pooler_config is None:
            return None

        pooling_task = self.pooler_config.task

        if pooling_task is not None:
            if self.pooler_config.task in supported_tasks:
                return self.pooler_config.task
            else:
                raise RuntimeError(
                    f"Unsupported task: {pooling_task!r} "
                    f"Supported tasks: {supported_tasks}"
                )

        if "token_classify" in supported_tasks:
            for architecture in self.architectures:
                if "ForTokenClassification" in architecture:
                    return "token_classify"

        priority: list[PoolingTask] = [
            "embed&token_classify",
            "embed",
            "classify",
            "token_embed",
            "token_classify",
            "plugin",
        ]
        for task in priority:

View on GitHub (pinned to c794754062)

Solutions

  1. Use one of the tasks listed in the error's Supported tasks list for that runner/model pair (e.g. 'embed', 'classify', 'score', 'reward').
  2. Omit the explicit task and let get_pooling_task infer it from the architecture (e.g. ForTokenClassification auto-selects 'token_classify').
  3. If you need a different task, serve the model with the runner that supports it (e.g. --runner pooling vs generate) or pick a model trained for that task.

Example fix

# before
vllm serve BAAI/bge-m3 --task classify
# after
vllm serve BAAI/bge-m3 --task embed
Defensive patterns

Strategy: validation

Validate before calling

def task_supported(task: str | None, supported: tuple) -> bool:
    return task is None or task in supported
# validate --pooling-task against the runner's supported tuple before serving

Type guard

from typing import Iterable
def is_supported_task(task: object, supported: Iterable[str]) -> bool:
    return isinstance(task, str) and task in supported

Try / catch

except RuntimeError as e:
    if 'Unsupported task' in str(e):
        parse the supported list from the message and surface it to the operator config UI

Prevention

When it happens

Trigger: PoolerConfig.task is set and get_pooling_task(supported_tasks) is called (e.g. serving with --task / --pooling-task classify) where the task string is not in the runner's supported tuple — including typo'd or runner-mismatched task names.

Common situations: Passing --task classify (a generation/score task) to an embedding runner, or 'score' to a classification model; mixing up vLLM task names across versions ('embed' vs 'embedding'); copy-pasting serve flags between different pooling models.

Related errors


AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14). Data as JSON: /api/errors/3151dce8b2bc118b. Report an issue: GitHub.