OpenBB-finance/OpenBB · error · ValueError

methods must be a list of strings

Error message

methods must be a list of strings

What it means

Raised by the mode='before' validator for the 'methods' field of the MCP HTTP route config. The validator first coerces a single string into a one-element list; anything that is still not a list afterwards (int, dict, tuple, None-like objects, nested lists) is rejected with this message. It wraps into a pydantic ValidationError at config parse time.

Source

Thrown at openbb_platform/extensions/mcp_server/openbb_mcp_server/models/mcp_config.py:175

        default_factory=list, description="Prompt configurations for this route."
    )
    exclude_args: list[str] | None = Field(
        default=None, description="List of argument names to exclude from this route."
    )

    @field_validator("methods", mode="before")
    @classmethod
    def validate_methods(cls, v: str | list[str] | None) -> list[HTTPMethod] | None:
        """Normalize and validate HTTP methods."""
        if v is None:
            return None

        # Handle single string
        if isinstance(v, str):
            v = [v]

        if not isinstance(v, list):
            raise ValueError("methods must be a list of strings")

        # If '*' is present, it should be the only method
        if "*" in v and len(v) > 1:
            raise ValueError("Method '*' cannot be mixed with other HTTP methods.")

        # Validate each method
        validated_methods = []
        for method in v:
            method_str = str(method).upper().strip() if method != "*" else "*"
            try:
                validated_methods.append(HTTPMethod(method_str))
            except ValueError as exc:
                valid_methods = [m.value for m in HTTPMethod]
                raise ValueError(
                    f"Invalid HTTP method '{method}'. Valid methods: {', '.join(valid_methods)}"
                ) from exc

        # Remove duplicates while preserving order

View on GitHub (pinned to 3e071fcc2c)

Solutions

  1. Change the value to a list of strings: "methods": ["GET", "POST"] or a single string "methods": "GET"
  2. If generating config programmatically, coerce with list(value) and ensure each element is a string
  3. Check YAML/JSON syntax around the methods key (a stray mapping or scalar where a sequence is expected)

Example fix

# before
openapi_extra={"mcp_config": {"methods": {"GET": True}}}

# after
openapi_extra={"mcp_config": {"methods": ["GET"]}}
Defensive patterns

Strategy: validation

Validate before calling

m = cfg.get("methods")
if isinstance(m, str):
    cfg["methods"] = [m]
elif not isinstance(m, list) or not all(isinstance(x, str) for x in m):
    raise ValueError("methods must be a str or list[str]")

Type guard

def is_valid_methods(v: object) -> bool:
    if isinstance(v, str):
        return True
    return isinstance(v, list) and all(isinstance(x, str) for x in v)

Try / catch

try:
    model = validate_mcp_config(cfg)
except ValidationError as e:
    if "methods must be a list" in str(e):
        cfg["methods"] = [str(x) for x in cfg["methods"]]  # or fix the source
        model = validate_mcp_config(cfg)
    else:
        raise

Prevention

When it happens

Trigger: Passing methods=123, methods={"GET": True}, or methods=("GET", "POST") (a tuple, not a list) in the mcp_config block; a JSON config that has "methods": "object" or a YAML mapping instead of a sequence. Note a plain string like "GET" is accepted and normalized to ["GET"].

Common situations: YAML indentation mistakes turning a list into a mapping, programmatic config builders emitting sets/tuples instead of lists, JSON configs authored by hand where methods is a dict of method->bool.

Related errors


AI-assisted analysis of OpenBB-finance/OpenBB@3e071fcc2c (2026-08-14). Data as JSON: /api/errors/1b89d16bc9719629. Report an issue: GitHub.