Skip to content

Inconsistent naming: convert endpoints use options, chunk endpoints use convert_options for same object -- silently drops settings #489

Description

@Ulli2060

Summary

The convert and chunk endpoints accept the same ConvertDocumentsRequestOptions object, but under different field names. Combined with Pydantic's default behavior of silently ignoring unknown fields, this causes user settings to be dropped without any error or warning.

Endpoints and their field names

Convert endpoints -- field: options

Endpoint Request model Conversion options field
POST /v1/convert/source ConvertDocumentsRequest options
POST /v1/convert/source/async ConvertDocumentsRequest options
{
  "options": { "pipeline": "vlm", ... },
  "sources": [...]
}

Chunk endpoints -- field: convert_options

Endpoint Request model Conversion options field Chunking options field
POST /v1/chunk/hybrid/source HybridChunkerOptionsDocumentsRequest convert_options chunking_options
POST /v1/chunk/hybrid/source/async HybridChunkerOptionsDocumentsRequest convert_options chunking_options
POST /v1/chunk/hierarchical/source HierarchicalChunkerOptionsDocumentsRequest convert_options chunking_options
POST /v1/chunk/hierarchical/source/async HierarchicalChunkerOptionsDocumentsRequest convert_options chunking_options
{
  "convert_options": { "pipeline": "vlm", ... },
  "chunking_options": { ... },
  "sources": [...]
}

Both options and convert_options reference the same type: ConvertDocumentsRequestOptions.

Problem

Since Pydantic BaseModel does not use extra="forbid", unknown fields are silently ignored:

  1. User sends "options": { "pipeline": "vlm", ... } to a chunk endpoint
  2. Pydantic silently drops options (unknown field at chunk endpoints)
  3. Default ConvertDocumentsRequestOptions() is used instead
  4. VLM pipeline config, OCR settings, custom prompts -- all ignored
  5. No error, no warning -- request succeeds with wrong defaults

Real-world impact: I spent significant time debugging why my VLM pipeline prompt overrides were being ignored at chunk endpoints. The root cause was simply that the field is called convert_options there, not options.

Proposed solution

Option A: Rename convert_options to options (preferred)

Use options consistently at all endpoints. The chunk-specific settings are already clearly separated in chunking_options, so there is no naming conflict.

Before After
Convert: options Convert: options (unchanged)
Chunk: convert_options + chunking_options Chunk: options + chunking_options

Option B: Add extra="forbid" to request models

Add model_config = ConfigDict(extra="forbid") to the base request model. This would raise a Pydantic validation error when unknown fields like options are sent to chunk endpoints, making the mistake immediately obvious.

This would be good practice regardless -- it prevents silent misconfiguration for any field name typo.

Ideally both: Rename for consistency and add extra="forbid" for safety.

Steps to reproduce

import httpx

# This works -- options is the correct field name for convert endpoints
convert_request = {
    "options": {"pipeline": "vlm"},
    "sources": [{"url": "https://example.com/doc.pdf"}]
}
r = httpx.post("http://localhost:5001/v1/convert/source", json=convert_request)
# Result: VLM pipeline is used correctly

# This SILENTLY FAILS -- options is ignored at chunk endpoints
chunk_request = {
    "options": {"pipeline": "vlm"},  # <-- silently dropped!
    "chunking_options": {"max_tokens": 512},
    "sources": [{"url": "https://example.com/doc.pdf"}]
}
r = httpx.post("http://localhost:5001/v1/chunk/hybrid/source", json=chunk_request)
# Result: default pipeline (standard) is used, VLM config silently ignored

# Correct chunk request requires convert_options instead
chunk_request_correct = {
    "convert_options": {"pipeline": "vlm"},  # <-- correct field name
    "chunking_options": {"max_tokens": 512},
    "sources": [{"url": "https://example.com/doc.pdf"}]
}

Related issues

Source code reference

File: docling_serve/datamodel/requests.py

# Convert endpoints use "options"
class ConvertDocumentsRequest(BaseDocumentsRequest):
    options: ConvertDocumentsRequestOptions = ConvertDocumentsRequestOptions()

# Chunk endpoints use "convert_options" for the same type
class HybridChunkerOptionsDocumentsRequest(BaseDocumentsRequest):
    convert_options: ConvertDocumentsRequestOptions = ConvertDocumentsRequestOptions()
    chunking_options: HybridChunkerOptions = HybridChunkerOptions()

Environment

  • docling-serve: v1.9.x / v1.10.x
  • Discovered via source code analysis of docling_serve/datamodel/requests.py

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions