OpenBMB/ChatDev · error · HTTPException

document_root_not_mapping

document_root_not_mapping

Error message

document_root_not_mapping

What it means

The YAML parsed successfully but the resulting value is not a mapping (dict). The schema loader expects the document root to be a mapping so load_design_from_mapping can process it. A bare scalar, list, or null root triggers this 422.

Source

Thrown at server/config_schema_router.py:53


@router.post("/schema")
def get_schema(request: SchemaRequest) -> Dict[str, Any]:
    try:
        return build_schema_response(request.breadcrumbs)
    except SchemaResolutionError as exc:
        raise HTTPException(status_code=422, detail={"message": str(exc)}) from exc


@router.post("/schema/validate")
def validate_document(request: SchemaValidateRequest) -> Dict[str, Any]:
    try:
        parsed = yaml.safe_load(request.document)
    except yaml.YAMLError as exc:
        raise HTTPException(status_code=400, detail={"message": "invalid_yaml", "error": str(exc)}) from exc

    if not isinstance(parsed, Mapping):
        raise HTTPException(status_code=422, detail={"message": "document_root_not_mapping"})

    try:
        load_design_from_mapping(parsed)
    except ConfigError as exc:
        return {
            "valid": False,
            "error": str(exc),
            "path": exc.path,
            "schema": _resolve_schema(request.breadcrumbs),
        }

    return {
        "valid": True,
        "schema": _resolve_schema(request.breadcrumbs),
    }


__all__ = ["router"]

View on GitHub (pinned to 4fb2db0ea9)

Solutions

  1. Ensure the top-level YAML structure uses key: value pairs
  2. If the document is a list, wrap it in a mapping (e.g. designs: [...])
  3. For empty documents, add at least a top-level key such as an empty mapping {}
  4. Check that you didn't paste a fragment that begins with a list item

Example fix

# before
- task: a
- task: b
# after
design:
  - task: a
  - task: b
Defensive patterns

Strategy: validation

Validate before calling

import yaml
from collections.abc import Mapping
def root_is_mapping(doc: str) -> bool:
    parsed = yaml.safe_load(doc)
    return isinstance(parsed, Mapping)

Type guard

from collections.abc import Mapping
def is_mapping_root(parsed) -> bool:
    return isinstance(parsed, Mapping)

Try / catch

if resp.status_code == 422 and resp.json()['detail']['message'] == 'document_root_not_mapping':
    # restructure document root as key: value pairs
    ...

Prevention

When it happens

Trigger: POST /schema/validate where the document root is a list (e.g. starts with '- '), a plain string, a number, or empty/null content (yaml.safe_load returns None for empty input).

Common situations: Submitting a YAML array of documents instead of a keyed config, submitting an empty string, wrapping the config under the wrong structure so the top level is a scalar.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of OpenBMB/ChatDev@4fb2db0ea9 (2026-08-27). Data as JSON: /api/errors/7041e36682c14760. Report an issue: GitHub.