{"record":{"id":"6b750b479cb87ef4","repo":"PrefectHQ/fastmcp","slug":"hidden-parameter-old-name-has-no-default-value","errorCode":null,"errorMessage":"Hidden parameter '{old_name}' has no default value in parent tool and no default or default_factory provided in ArgTransform. Either provide a default or default_factory in ArgTransform or don't hide required parameters.","messagePattern":"Hidden parameter '(.+?)' has no default value in parent tool and no default or default_factory provided in ArgTransform\\. Either provide a default or default_factory in ArgTransform or don't hide required parameters\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/tools/tool_transform.py","lineNumber":675,"sourceCode":"        hidden_defaults = {}  # Track hidden parameters with constant values\n\n        for old_name, old_schema in parent_props.items():\n            # Check if parameter is in transform_args\n            if transform_args and old_name in transform_args:\n                transform = transform_args[old_name]\n            else:\n                # Default behavior - pass through (no transformation)\n                transform = ArgTransform()  # Default ArgTransform with no changes\n\n            # Handle hidden parameters with defaults\n            if transform.hide:\n                # Validate that hidden parameters without user defaults have parent defaults\n                has_user_default = (\n                    transform.default is not NotSet\n                    or transform.default_factory is not NotSet\n                )\n                if not has_user_default and old_name in parent_required:\n                    raise ValueError(\n                        f\"Hidden parameter '{old_name}' has no default value in parent tool \"\n                        f\"and no default or default_factory provided in ArgTransform. Either provide a default \"\n                        f\"or default_factory in ArgTransform or don't hide required parameters.\"\n                    )\n                if has_user_default:\n                    # Store info for later factory calling or direct value\n                    hidden_defaults[old_name] = transform\n                # Skip adding to schema (not exposed to clients)\n                continue\n\n            transform_result = cls._apply_single_transform(\n                old_name,\n                old_schema,\n                transform,\n                old_name in parent_required,\n            )\n\n            if transform_result:","sourceCodeStart":657,"sourceCodeEnd":693,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/tools/tool_transform.py#L657-L693","documentation":"When _create_forwarding_transform hides a parameter, that parameter can never be supplied by clients, so it needs a value at call time. If the parent tool marks it required and the ArgTransform supplies neither default nor default_factory, there is no way to fill it, so ValueError is raised explaining the options.","triggerScenarios":"ArgTransform(hide=True) on a parameter listed in the parent tool's required properties, without default= or default_factory=.","commonSituations":"Hiding a required API-key/token param from the exposed schema but forgetting to inject its value; hiding required params after a parent tool change made them required.","solutions":["Provide default=<static value> (or default_factory=<callable>) in the ArgTransform alongside hide=True.","Read the value from config/env when building the transform: ArgTransform(hide=True, default=os.environ[\"API_KEY\"]).","Don't hide the parameter if clients should supply it.","Supply it inside the replacement function via forward_raw if the value is computed at call time."],"exampleFix":"// before\nArgTransform(name=\"api_key\", hide=True)  # parent requires api_key\n\n// after\nArgTransform(name=\"api_key\", hide=True, default_factory=lambda: os.environ[\"API_KEY\"])","handlingStrategy":"validation","validationCode":"def check_hidden_has_value(tool, transform_args: dict) -> None:\n    required = set(tool.parameters.get(\"required\", []))\n    for name, t in transform_args.items():\n        if t.hide and name in required and t.default is NotSet and t.default_factory is NotSet:\n            raise ValueError(f\"Hidden required param '{name}' needs default or default_factory\")","typeGuard":null,"tryCatchPattern":"try:\n    t = ParentTool.from_tool(tool, transform_args=ta)\nexcept ValueError as e:\n    if \"has no default value\" in str(e):\n        log.error(\"Provide default/default_factory for hidden required params: %s\", e)\n    raise","preventionTips":["Before hiding a param, check whether the parent tool lists it as required.","Inject hidden values from environment/config at transform construction time.","Prefer default_factory for secrets so they are resolved fresh at call time."],"tags":["python","tool-transform","validation"],"backgroundTag":"missing-required-parameter-default","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}