reactiveui/refit · error · ArgumentException
Only one parameter can be a HeaderCollection parameter
Error message
Only one parameter can be a HeaderCollection parameter
What it means
Refit permits at most one header-collection parameter per method because it needs a single target to assign the header dictionary to. The loop tracks the first header-collection index and throws if it finds a second one.
Source
Thrown at src/Refit.Reflection/RestMethodInfoInternal.AttributeReading.cs:136
for (var i = 0; i < parameterArray.Length; i++)
{
if (sets[i].HeaderCollection is null)
{
continue;
}
// Opted for IDictionary<string, string> semantics here as opposed to the looser
// IEnumerable<KeyValuePair<string, string>> because IDictionary enforces unique keys.
if (!parameterArray[i].ParameterType.IsAssignableFrom(typeof(IDictionary<string, string>)))
{
throw new ArgumentException(
$"HeaderCollection parameter of type {parameterArray[i].ParameterType.Name} is not assignable from IDictionary<string, string>");
}
// Throw if there is already a HeaderCollection parameter.
if (headerIndex >= 0)
{
throw new ArgumentException("Only one parameter can be a HeaderCollection parameter");
}
headerIndex = i;
}
return headerIndex;
}
/// <summary>Builds the map of parameter indexes to request property keys.</summary>
/// <param name="parameterArray">The array of method parameters.</param>
/// <param name="sets">The classified attribute set for each parameter.</param>
/// <returns>A map of parameter indexes to property keys.</returns>
internal static Dictionary<int, string> BuildRequestPropertyMap(ParameterInfo[] parameterArray, ParameterAttributeSet[] sets)
{
Dictionary<int, string>? propertyMap = null;
for (var i = 0; i < parameterArray.Length; i++)
{View on GitHub (pinned to b455f65ecc)
Solutions
- Merge multiple header-collection parameters into a single IDictionary<string,string>.
- If you need individual headers, use single [Header("name")] string parameters instead of a second collection.
Example fix
// before
[Get("/x")] Task GetAsync([HeaderCollection] IDictionary<string,string> a,
[HeaderCollection] IDictionary<string,string> b);
// after
[Get("/x")] Task GetAsync([HeaderCollection] IDictionary<string,string> all);
// caller merges: all = new[] { a, b }.SelectMany(d => d).ToDictionary(...) Defensive patterns
Strategy: validation
Validate before calling
static void AssertSingleHeaderCollection(MethodInfo m) {
var count = m.GetParameters().Count(p => /* has header-collection attribute */ false);
if (count > 1) throw new InvalidOperationException("Multiple header-collection params on " + m.Name);
} Prevention
- Allow only one header-collection parameter per method.
- Merge multiple header dictionaries before the call.
- Use individual [Header] params for specific headers.
When it happens
Trigger: Two (or more) parameters on the same Refit interface method are both bound as header collections.
Common situations: Copy-pasting a header parameter into a second argument; combining an inherited header-collection param with a new one; refactor merging header params.
Related errors
- HeaderCollection parameter of type {parameterArray[i].Parame
- Method must be defined and have an HTTP Method attribute
- Only one parameter can be an Authorize parameter
- URL {relativePath} has parameter {rawName}, but no method pa
- A [Url] method must not also declare a path template; [Url]
AI-assisted analysis of reactiveui/refit@b455f65ecc (2026-08-13).
Data as JSON: /api/errors/97ab678c57119a5d.
Report an issue: GitHub.