{"record":{"id":"ecf52a9d62eee2f3","repo":"langchain-ai/langchain","slug":"arg-docstring-arg-in-docstring-not-found-in-func","errorCode":null,"errorMessage":"Arg {docstring_arg} in docstring not found in function signature.","messagePattern":"Arg (.+?) in docstring not found in function signature\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/tools/base.py","lineNumber":168,"sourceCode":"    )\n\n\ndef _validate_docstring_args_against_annotations(\n    arg_descriptions: dict[str, str], annotations: dict[str, Any]\n) -> None:\n    \"\"\"Validate that docstring arguments match function annotations.\n\n    Args:\n        arg_descriptions: Arguments described in the docstring.\n        annotations: Type annotations from the function signature.\n\n    Raises:\n        ValueError: If a docstring argument is not found in function signature.\n    \"\"\"\n    for docstring_arg in arg_descriptions:\n        if docstring_arg not in annotations:\n            msg = f\"Arg {docstring_arg} in docstring not found in function signature.\"\n            raise ValueError(msg)\n\n\ndef _infer_arg_descriptions(\n    fn: Callable[..., Any],\n    *,\n    parse_docstring: bool = False,\n    error_on_invalid_docstring: bool = False,\n) -> tuple[str, dict[str, str]]:\n    \"\"\"Infer argument descriptions from function docstring and annotations.\n\n    Args:\n        fn: The function to infer descriptions from.\n        parse_docstring: Whether to parse the docstring for descriptions.\n        error_on_invalid_docstring: Whether to raise error on invalid docstring.\n\n    Returns:\n        A tuple containing the function description and argument descriptions.\n    \"\"\"","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/tools/base.py#L150-L186","documentation":"When `@tool` is created with `parse_docstring=True` (Google-style Args: parsing), langchain validates that every argument documented in the docstring exists in the function signature. A documented arg with no matching parameter raises this ValueError at tool-creation time, catching stale docstrings before they produce a broken JSON schema.","triggerScenarios":"`@tool(parse_docstring=True)` on a function whose `Args:` section lists a parameter that was renamed or removed (docstring says `query: ...` but the function takes `q`); typos in the Args section; documented kwargs that are not explicit parameters.","commonSituations":"Renaming a tool function's parameter without updating its Google-style docstring; copying a docstring template between tools; enabling `parse_docstring=True` on legacy tools whose docstrings were never validated.","solutions":["Make the docstring `Args:` entries exactly match the function parameter names (spelling and order of names).","Rename the docstring arg or the function parameter so both sides agree.","If the docstring is wrong and you cannot fix it now, drop `parse_docstring=True` and pass `description`/`args_schema` explicitly instead."],"exampleFix":"# before\n@tool(parse_docstring=True)\ndef search(q: str) -> str:\n    \"\"\"Search.\n\n    Args:\n        query: the query  # no param named 'query'\n    \"\"\"\n# after\n@tool(parse_docstring=True)\ndef search(q: str) -> str:\n    \"\"\"Search.\n\n    Args:\n        q: the query\n    \"\"\"","handlingStrategy":"validation","validationCode":"import inspect\n\ndef docstring_args_match(fn) -> bool:\n    import re\n    doc = fn.__doc__ or ''\n    m = re.search(r'Args:\\s*(.*?)(?:\\n\\n|Returns:|$)', doc, re.S)\n    if not m:\n        return True\n    documented = {line.split(':')[0].strip() for line in m.group(1).splitlines() if ':' in line}\n    signature = set(inspect.signature(fn).parameters)\n    return documented <= signature\n\nassert docstring_args_match(fn)","typeGuard":null,"tryCatchPattern":"try:\n    tool = tool_decorator(parse_docstring=True)(fn)\nexcept ValueError as e:\n    if 'not found in function signature' in str(e):\n        tool = tool_decorator(parse_docstring=False)(fn)  # fix docstring later\n    else:\n        raise","preventionTips":["Keep Args: entries exactly in sync with parameter names.","Add a CI lint that compares docstring args to inspect.signature.","Rename parameters and docstring entries together in one commit."],"tags":["tool","docstring","parse-docstring","validation"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}