{"record":{"id":"61378d0416f929fb","repo":"OpenBB-finance/OpenBB","slug":"method-must-be-get-or-post","errorCode":null,"errorMessage":"Method must be GET or POST","messagePattern":"Method must be GET or POST","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"openbb_platform/core/openbb_core/provider/utils/helpers.py","lineNumber":565,"sourceCode":"\n    # Allow a custom session for caching, if desired\n    _session = kwargs.pop(\"session\", get_requests_session(**kwargs))\n\n    if method.upper() == \"GET\":\n        return _session.get(\n            url,\n            headers=headers,\n            timeout=timeout,\n            **kwargs,\n        )\n    if method.upper() == \"POST\":\n        return _session.post(\n            url,\n            headers=headers,\n            timeout=timeout,\n            **kwargs,\n        )\n    raise ValueError(\"Method must be GET or POST\")\n\n\ndef to_snake_case(string: str) -> str:\n    \"\"\"Convert a string to snake case.\"\"\"\n    import re  # pylint: disable=import-outside-toplevel\n\n    s1 = re.sub(\"(.)([A-Z][a-z]+)\", r\"\\1_\\2\", string)\n    return (\n        re.sub(\"([a-z0-9])([A-Z])\", r\"\\1_\\2\", s1)\n        .lower()\n        .replace(\" \", \"_\")\n        .replace(\"__\", \"_\")\n    )\n\n\nasync def maybe_coroutine(\n    func: Callable[P, T | Awaitable[T]], /, *args: P.args, **kwargs: P.kwargs\n) -> T:","sourceCodeStart":547,"sourceCodeEnd":583,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/core/openbb_core/provider/utils/helpers.py#L547-L583","documentation":"Raised by openbb_core.provider.utils.helpers.make_request (and its async twin amake_request) when the 'method' argument, after .upper(), is neither 'GET' nor 'POST'. The helper deliberately supports only these two verbs; anything else ('PUT', 'DELETE', lowercase variants are fine) raises ValueError before any HTTP call is made.","triggerScenarios":"Calling make_request(url, method='PUT'|'DELETE'|'PATCH'|'HEAD'|'OPTIONS') directly from a custom provider fetcher, or passing an unvalidated user-supplied method string through to it.","commonSituations":"Custom provider authors porting code from requests.sessions.Session (which supports all verbs) into OpenBB's helper; building a generic proxy that forwards arbitrary HTTP methods.","solutions":["Restrict the call to method='GET' or method='POST'","If you truly need other verbs, use the session object directly: get_requests_session().put(url, ...) from openbb_core.provider.utils.helpers","Validate/whitelist the method at your API boundary before it reaches make_request"],"exampleFix":"# before\nresp = make_request(url, method=\"DELETE\")  # ValueError: Method must be GET or POST\n\n# after\nfrom openbb_core.provider.utils.helpers import get_requests_session\nresp = get_requests_session().delete(url, timeout=10)","handlingStrategy":"type-guard","validationCode":"ALLOWED_METHODS = {\"GET\", \"POST\"}\n\nmethod = method.upper()\nif method not in ALLOWED_METHODS:\n    raise ValueError(f\"unsupported method {method}; use one of {sorted(ALLOWED_METHODS)}\")","typeGuard":"from typing import Literal\n\nHttpMethod = Literal[\"GET\", \"POST\"]\n\ndef is_supported_method(m: str) -> bool:\n    return m.upper() in {\"GET\", \"POST\"}","tryCatchPattern":"from openbb_core.provider.utils.helpers import make_request\n\ntry:\n    resp = make_request(url, method=method)\nexcept ValueError as e:\n    if \"Method must be GET or POST\" in str(e):\n        resp = get_requests_session().request(method, url)  # escape hatch for other verbs\n    else:\n        raise","preventionTips":["Type method parameters as Literal['GET','POST'] so static checkers catch bad calls","Whitelist and uppercase the method at your API boundary","For arbitrary verbs, use the session from get_requests_session() directly instead of make_request"],"tags":["http","method-not-allowed","network","provider-dev"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}