{"record":{"id":"92decc6d689c8b16","repo":"reactiveui/refit","slug":"url-relativepath-has-parameter-rawname-but-no","errorCode":null,"errorMessage":"URL {relativePath} has parameter {rawName}, but no method parameter matches","messagePattern":"URL (.+?) has parameter (.+?), but no method parameter matches","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Refit.Reflection/RestMethodInfoInternal.ParameterBinding.cs","lineNumber":182,"sourceCode":"            && (validation.Object ??= BuildObjectParamValidationDict(parameterInfo)).TryGetValue(name, out var value1))\n        {\n            AddObjectPropertyParameter(parameterInfo, ret, fragmentList, name, value1.Parameter, [value1.Property], isOptional);\n        }\n        else if (TryResolveNestedPropertyChain(parameterInfo, name) is { } nested)\n        {\n            // A round-trip placeholder only ever matches a direct parameter above, so it never reaches a nested chain\n            // (which requires a dotted name); no isRoundTripping guard is needed here.\n            AddObjectPropertyParameter(parameterInfo, ret, fragmentList, name, nested.Parameter, nested.Chain, isOptional);\n        }\n        else if (allowUnmatchedRouteParameters)\n        {\n            // Leave the unmatched placeholder in the URL verbatim (including its braces) so the\n            // caller can resolve it later, e.g. inside a DelegatingHandler.\n            fragmentList.Add(ParameterFragment.Constant(match.Value));\n        }\n        else\n        {\n            throw new ArgumentException(\n                $\"URL {relativePath} has parameter {rawName}, but no method parameter matches\");\n        }\n    }\n\n    /// <summary>Adds a standard (directly matched) route parameter to the parameter map and fragment list.</summary>\n    /// <param name=\"parameterInfo\">The array of method parameters.</param>\n    /// <param name=\"ret\">The parameter map being built.</param>\n    /// <param name=\"fragmentList\">The fragment list being built.</param>\n    /// <param name=\"parsedName\">The parsed parameter name details from the URL template.</param>\n    /// <param name=\"value\">The matched method parameter.</param>\n    /// <param name=\"isOptional\">Whether the placeholder was declared optional with the <c>{name?}</c> syntax.</param>\n    internal static void AddStandardParameter(\n        ParameterInfo[] parameterInfo,\n        Dictionary<int, RestMethodParameterInfo> ret,\n        List<ParameterFragment> fragmentList,\n        ParsedParameterName parsedName,\n        ParameterInfo value,\n        bool isOptional)","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/reactiveui/refit/blob/b455f65ecc4c97d092317e349cb775f9cfc6bcdf/src/Refit.Reflection/RestMethodInfoInternal.ParameterBinding.cs#L164-L200","documentation":"While parsing the URL path template, Refit found a placeholder like {foo} but no method parameter matches it by name, no object-property resolves it, and no nested property chain matches. When allowUnmatchedRouteParameters is off, unmatched placeholders are rejected so typos surface immediately rather than producing a malformed URL.","triggerScenarios":"A route placeholder name does not correspond to any method parameter or object-property chain, e.g. [Get(\"/users/{id}\")] with a parameter named userId, or a placeholder for a property that does not exist.","commonSituations":"Renamed a parameter but not the template; placeholder typo; expected a property on a parameter object that does not exist; mismatched AliasAs.","solutions":["Make the placeholder name match a method parameter name (or its [AliasAs] value).","If the value comes from an object, ensure a matching public property or chain exists on that object.","If the placeholder is intentionally resolved later (e.g. in a DelegatingHandler), enable allowUnmatchedRouteParameters in RefitSettings."],"exampleFix":"// before\n[Get(\"/users/{id}\")] Task<User> GetAsync(int userId); // {id} has no match\n\n// after\n[Get(\"/users/{id}\")] Task<User> GetAsync(int id);","handlingStrategy":"validation","validationCode":"// Check each placeholder has a matching parameter before runtime.\nvar template = \"/users/{id}\";\nvar placeholders = System.Text.RegularExpressions.Regex.Matches(template, @\"\\{(\\??[\\w.]+)\\}\");\nforeach (System.Text.RegularExpressions.Match ph in placeholders) {\n    var name = ph.Groups[1].Value.TrimEnd('?');\n    if (!parameterNames.Contains(name)) throw new InvalidOperationException($\"Unmatched placeholder {{{name}}}\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep route placeholder names in sync with parameter names/AliasAs.","Enable allowUnmatchedRouteParameters only when intentionally deferring resolution.","Add a startup test that builds the client to surface template errors early."],"tags":["refit","routing","url-template","attributes","design-time"],"backgroundTag":null,"analyzedSha":"b455f65ecc4c97d092317e349cb775f9cfc6bcdf","analyzedAt":"2026-08-13T21:20:57.878Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}