reactiveui/refit · error · ArgumentException

URL {relativePath} has parameter {rawName}, but no method pa

Error message

URL {relativePath} has parameter {rawName}, but no method parameter matches

What it means

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.

Source

Thrown at src/Refit.Reflection/RestMethodInfoInternal.ParameterBinding.cs:182

            && (validation.Object ??= BuildObjectParamValidationDict(parameterInfo)).TryGetValue(name, out var value1))
        {
            AddObjectPropertyParameter(parameterInfo, ret, fragmentList, name, value1.Parameter, [value1.Property], isOptional);
        }
        else if (TryResolveNestedPropertyChain(parameterInfo, name) is { } nested)
        {
            // A round-trip placeholder only ever matches a direct parameter above, so it never reaches a nested chain
            // (which requires a dotted name); no isRoundTripping guard is needed here.
            AddObjectPropertyParameter(parameterInfo, ret, fragmentList, name, nested.Parameter, nested.Chain, isOptional);
        }
        else if (allowUnmatchedRouteParameters)
        {
            // Leave the unmatched placeholder in the URL verbatim (including its braces) so the
            // caller can resolve it later, e.g. inside a DelegatingHandler.
            fragmentList.Add(ParameterFragment.Constant(match.Value));
        }
        else
        {
            throw new ArgumentException(
                $"URL {relativePath} has parameter {rawName}, but no method parameter matches");
        }
    }

    /// <summary>Adds a standard (directly matched) route parameter to the parameter map and fragment list.</summary>
    /// <param name="parameterInfo">The array of method parameters.</param>
    /// <param name="ret">The parameter map being built.</param>
    /// <param name="fragmentList">The fragment list being built.</param>
    /// <param name="parsedName">The parsed parameter name details from the URL template.</param>
    /// <param name="value">The matched method parameter.</param>
    /// <param name="isOptional">Whether the placeholder was declared optional with the <c>{name?}</c> syntax.</param>
    internal static void AddStandardParameter(
        ParameterInfo[] parameterInfo,
        Dictionary<int, RestMethodParameterInfo> ret,
        List<ParameterFragment> fragmentList,
        ParsedParameterName parsedName,
        ParameterInfo value,
        bool isOptional)

View on GitHub (pinned to b455f65ecc)

Solutions

  1. Make the placeholder name match a method parameter name (or its [AliasAs] value).
  2. If the value comes from an object, ensure a matching public property or chain exists on that object.
  3. If the placeholder is intentionally resolved later (e.g. in a DelegatingHandler), enable allowUnmatchedRouteParameters in RefitSettings.

Example fix

// before
[Get("/users/{id}")] Task<User> GetAsync(int userId); // {id} has no match

// after
[Get("/users/{id}")] Task<User> GetAsync(int id);
Defensive patterns

Strategy: validation

Validate before calling

// Check each placeholder has a matching parameter before runtime.
var template = "/users/{id}";
var placeholders = System.Text.RegularExpressions.Regex.Matches(template, @"\{(\??[\w.]+)\}");
foreach (System.Text.RegularExpressions.Match ph in placeholders) {
    var name = ph.Groups[1].Value.TrimEnd('?');
    if (!parameterNames.Contains(name)) throw new InvalidOperationException($"Unmatched placeholder {{{name}}}");
}

Prevention

When it happens

Trigger: 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.

Common situations: Renamed a parameter but not the template; placeholder typo; expected a property on a parameter object that does not exist; mismatched AliasAs.

Related errors


AI-assisted analysis of reactiveui/refit@b455f65ecc (2026-08-13). Data as JSON: /api/errors/92decc6d689c8b16. Report an issue: GitHub.