{"record":{"id":"62a5ed9cf265a7e2","repo":"PrefectHQ/fastmcp","slug":"uri-parameters-all-uri-params-must-be-a-subset-o","errorCode":null,"errorMessage":"URI parameters {all_uri_params} must be a subset of the function arguments: {func_params}","messagePattern":"URI parameters (.+?) must be a subset of the function arguments: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/resources/template.py","lineNumber":532,"sourceCode":"            invalid_query_params = query_params - optional_params\n            if invalid_query_params:\n                raise ValueError(\n                    f\"Query parameters {invalid_query_params} must be optional function parameters with default values\"\n                )\n\n        # Check if required parameters are a subset of the path parameters\n        if not required_params.issubset(path_params):\n            raise ValueError(\n                f\"Required function arguments {required_params} must be a subset of the URI path parameters {path_params}\"\n            )\n\n        # Check if all URI parameters are valid function parameters (skip if **kwargs present)\n        if not any(\n            param.kind == inspect.Parameter.VAR_KEYWORD\n            for param in sig.parameters.values()\n        ):\n            if not all_uri_params.issubset(func_params):\n                raise ValueError(\n                    f\"URI parameters {all_uri_params} must be a subset of the function arguments: {func_params}\"\n                )\n\n        description = description if description is not None else inspect.getdoc(fn)\n\n        # if the fn is a callable class, we need to get the __call__ method from here out\n        if not inspect.isroutine(fn) and not isinstance(fn, functools.partial):\n            fn = fn.__call__\n        # if the fn is a staticmethod, we need to work with the underlying function\n        if isinstance(fn, staticmethod):\n            fn = fn.__func__\n\n        # Transform Context type annotations to Depends() for unified DI\n        fn = transform_context_annotations(fn)\n\n        wrapper_fn = without_injected_parameters(fn)\n        type_adapter = get_cached_typeadapter(wrapper_fn)\n        parameters = type_adapter.json_schema()","sourceCodeStart":514,"sourceCodeEnd":550,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/resources/template.py#L514-L550","documentation":"Every {param} in the URI template must correspond to a declared function parameter so values can be passed when the template matches. This check is skipped when the function has **kwargs, which absorbs any URI parameter by name. Otherwise a URI parameter with no matching function parameter raises this error.","triggerScenarios":"Registering a template whose URI references a parameter the function doesn't declare (typo or leftover placeholder), and the function has no **kwargs.","commonSituations":"Renaming a function parameter without updating the URI template; editing the URI template by hand and adding a placeholder the function never accepted; case-sensitivity mismatches between URI and Python names.","solutions":["Add a function parameter with the same name as the URI placeholder","Fix the URI template so its placeholders match the existing function parameters","Accept **kwargs in the function if you intentionally want to absorb arbitrary URI params"],"exampleFix":"// before\ndef get(key: str): ...\nResourceTemplate.from_function(get, uri_template=\"data://{key}/{version}\")\n// after\ndef get(key: str, version: str): ...\nResourceTemplate.from_function(get, uri_template=\"data://{key}/{version}\")","handlingStrategy":"validation","validationCode":"import inspect, re\ndef check_uri_params_covered(fn, uri_template):\n    allp = {p.replace(\"-\", \"_\") for p in re.findall(r\"\\{(\\w[-\\w]*)\\}\", uri_template)}\n    params = inspect.signature(fn).parameters\n    has_kw = any(p.kind is inspect.Parameter.VAR_KEYWORD for p in params.values())\n    if not has_kw and not allp <= set(params):\n        raise TypeError(f\"URI params {allp - set(params)} not in function\")","typeGuard":"def uri_params_covered(fn, uri_template) -> bool:\n    import inspect, re\n    allp = {p.replace(\"-\", \"_\") for p in re.findall(r\"\\{(\\w[-\\w]*)\\}\", uri_template)}\n    params = inspect.signature(fn).parameters\n    if any(p.kind is inspect.Parameter.VAR_KEYWORD for p in params.values()):\n        return True\n    return allp <= set(params)","tryCatchPattern":"try:\n    tpl = FunctionResourceTemplate.from_function(fn, uri_template=uri)\nexcept ValueError as e:\n    if \"must be a subset of the function arguments\" in str(e):\n        raise TypeError(f\"Align {uri!r} placeholders with {fn.__name__} signature\") from e\n    raise","preventionTips":["Keep the URI template and function signature in adjacent code and change them together","Add a unit test asserting placeholder/signature parity for every template","Fix typos in placeholders (they must match Python parameter names after hyphen normalization)"],"tags":["uri-template","validation","signature"],"backgroundTag":"uri-parameter-unmatched","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}