opendatalab/MinerU · error · ValueError

effort must be "medium" or "high"

Error message

effort must be "medium" or "high"

What it means

Raised by _validate_parse_effort() in the Hybrid backend when the effort argument is not in HYBRID_ANALYZE_EFFORTS (only "medium" and "high"). The validation exists to prevent silently falling into the wrong analysis-strength branch; anything other than the two allowed strings aborts immediately.

Source

Thrown at mineru/backend/hybrid/hybrid_analyze.py:113

    "number": BlockType.PAGE_NUMBER,
    "paragraph_title": BlockType.TITLE,
    "reference_content": BlockType.REF_TEXT,
    "text": BlockType.TEXT,
    "vertical_text": BlockType.TEXT,
    "figure_title": BlockType.IMAGE_CAPTION,
    "vision_footnote": BlockType.IMAGE_FOOTNOTE,
    "image": BlockType.IMAGE,
    "chart": BlockType.CHART,
    "seal": BlockType.IMAGE,
    "table": BlockType.TABLE,
    "display_formula": BlockType.EQUATION,
}


def _validate_parse_effort(effort: str = "medium") -> str:
    """校验 Hybrid effort,避免静默走错解析强度分支。"""
    if effort not in HYBRID_ANALYZE_EFFORTS:
        raise ValueError('effort must be "medium" or "high"')
    return effort


def _resolve_effective_image_analysis(effort: str, image_analysis: bool) -> bool:
    """根据 Hybrid 解析强度计算实际图片分析开关;medium 强制关闭以保持快速路径。"""
    if effort == "medium":
        return False
    return image_analysis


def _vlm_type_for_medium_layout_label(label: str | None) -> str | None:
    """将 pipeline layout 标签映射为 mineru-vl-utils 支持的 VLM 抽取类型。"""
    return MEDIUM_EFFORT_LAYOUT_LABEL_TO_VLM_TYPE.get(label)


def _apply_medium_visual_sub_type(block, label: str | None):
    """为视觉块补充下游需要透传的子类型。"""
    if label == "seal":

View on GitHub (pinned to 4fe4bde114)

Solutions

  1. Set effort to "medium" (fast path, image analysis forced off) or "high".
  2. Check HYBRID_ANALYZE_EFFORTS in mineru/backend/hybrid/hybrid_analyze.py for the authoritative allowed set in your version.
  3. Validate/normalize user-supplied effort at your config boundary (lowercase, membership check).

Example fix

# before
result = hybrid_analyze(pdf, effort="low")

# after
result = hybrid_analyze(pdf, effort="high")
Defensive patterns

Strategy: validation

Validate before calling

from mineru.backend.hybrid.hybrid_analyze import HYBRID_ANALYZE_EFFORTS

def normalize_effort(effort: str) -> str:
    effort = (effort or "medium").strip().lower()
    if effort not in HYBRID_ANALYZE_EFFORTS:
        raise ValueError(f"effort must be one of {sorted(HYBRID_ANALYZE_EFFORTS)}")
    return effort

Type guard

from mineru.backend.hybrid.hybrid_analyze import HYBRID_ANALYZE_EFFORTS

def is_valid_effort(value: object) -> bool:
    return isinstance(value, str) and value in HYBRID_ANALYZE_EFFORTS

Try / catch

try:
    vlm_analyze(..., effort=effort)
except ValueError as e:
    if 'effort must be' in str(e):
        vlm_analyze(..., effort="medium")  # explicit fallback to default
    else:
        raise

Prevention

When it happens

Trigger: Calling hybrid analysis with effort="low", effort="", or a future/unrecognized value; passing None; passing uppercase "HIGH" (values are case-sensitive).

Common situations: Porting configs from other APIs where effort="low" is valid (e.g. OpenAI-style effort levels); typos; sharing config files across backend versions.

Related errors


AI-assisted analysis of opendatalab/MinerU@4fe4bde114 (2026-08-14). Data as JSON: /api/errors/2ae7084a1fc0c754. Report an issue: GitHub.