sgl-project/sglang · error · ValueError

invalid reasoning effort: {effort!r}

Error message

invalid reasoning effort: {effort!r}

What it means

Raised by ChatCompletionRequest.normalize_reasoning_inputs when the reasoning dict's 'effort' key is a string that cannot be coerced to a float (e.g. 'highx'). SGLang accepts numeric strings for effort, matching the lax union of the top-level reasoning_effort field, but anything non-numeric fails here.

Source

Thrown at python/sglang/srt/entrypoints/openai/protocol.py:1011

            if isinstance(effort, str) and effort in {
                "none",
                "minimal",
                "low",
                "medium",
                "high",
                "xhigh",
                "max",
            }:
                values["reasoning_effort"] = effort
            elif isinstance(effort, (int, float)) and not isinstance(effort, bool):
                values["reasoning_effort"] = float(effort)
            elif isinstance(effort, str):
                # Keep parity with the top-level reasoning_effort field, whose
                # lax union coerces numeric strings; range checks then apply.
                try:
                    values["reasoning_effort"] = float(effort)
                except ValueError as exc:
                    raise ValueError(f"invalid reasoning effort: {effort!r}") from exc
            elif effort is not None:
                raise ValueError(f"invalid reasoning effort: {effort!r}")

            enabled = (
                r.get("enabled")
                if r.get("enabled") is not None
                else r.get("enable", False)
            )
            if isinstance(enabled, str):
                enabled = enabled.strip().lower() in {"1", "true", "yes", "y", "on"}
            if enabled:
                thinking = True

        effort = values.get("reasoning_effort")
        if effort is not None:
            thinking = effort != "none"

        if thinking is not None:

View on GitHub (pinned to 0132848349)

Solutions

  1. Use a numeric string or number, e.g. "effort": "0.7" or 0.7, or a supported label like 'low'/'medium'/'high' where mapped elsewhere
  2. Remove the effort key to use the server default
  3. Check the reasoning dict shape: {"reasoning": {"effort": <number|numeric-string>}}

Example fix

// before
{"reasoning": {"effort": "maximun"}}
// after
{"reasoning": {"effort": 0.9}}
Defensive patterns

Strategy: validation

Validate before calling

effort = req.get("reasoning", {}).get("effort")
if isinstance(effort, str):
    try:
        float(effort)
    except ValueError:
        raise ValueError("effort must be numeric or a numeric string")

Type guard

def is_valid_effort(e) -> bool:
    return e is None or isinstance(e, (int, float)) or (isinstance(e, str) and _float_ok(e))

Try / catch

try: client.chat.completions.create(...)
except ValueError as e: if 'invalid reasoning effort' in str(e): fix effort

Prevention

When it happens

Trigger: POST /v1/chat/completions with body {"reasoning": {"effort": "abc"}} where 'abc' is not parseable by float().

Common situations: Typos in effort strings like 'hi' or 'maximum'; passing model-specific effort labels that only some models (e.g. Inkling/Harmony) recognize; assuming any string label is accepted.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/10897dcf9db19050. Report an issue: GitHub.