git-ecosystem/git-credential-manager · error · ArgumentException

Cannot render the None capability to a protocol name.

Error message

Cannot render the None capability to a protocol name.

What it means

GitCapabilities.ToProtocolName maps a GitCapabilities.State enum value to the wire protocol capability name string. The None sentinel does not represent a real capability, so it can never be rendered; calling ToProtocolName with it throws ArgumentException naming the parameter. ToProtocolNames callers should filter None out before mapping.

Solutions

  1. Filter out GitCapabilities.None before calling ToProtocolNames/ToProtocolName.
  2. Ensure the capabilities value is populated with actual capabilities (e.g. State) before serialization.
  3. Guard with an explicit check and skip rendering when capability == GitCapabilities.None.

Example fix

// before
var names = capabilities.ToProtocolNames(); // includes None
// after
if (capabilities.HasFlag(GitCapabilities.None))
    capabilities &= ~GitCapabilities.None;
var names = capabilities.ToProtocolNames();
Defensive patterns

Strategy: validation

Validate before calling

if (capabilities.HasFlag(GitCapabilities.None))
    capabilities &= ~GitCapabilities.None;
var protocolNames = capabilities.ToProtocolNames();

Type guard

bool IsRenderableCapability(GitCapabilities.State c) => c != GitCapabilities.None;

Try / catch

try
{
    var name = capability.ToProtocolName();
}
catch (ArgumentException)
{
    // capability was None; skip rendering it
}

Prevention

When it happens

Trigger: Calling ToProtocolName(GitCapabilities.None) directly, or via ToProtocolNames when a capabilities set includes the None flag without being filtered, e.g. building protocol capability strings from a default/unset capabilities enum.

Common situations: Code that initializes a capabilities variable to GitCapabilities.None and forgets to add real capabilities before serializing to the Git protocol; custom integrations constructing capability lists programmatically.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of git-ecosystem/git-credential-manager@e8ce762cd0 (2026-09-11). Data as JSON: /api/errors/75e2300a5aa8380f. Report an issue: GitHub.

Appendix: source

Thrown at src/Core/GitCapabilities.cs:93

    /// Render a single <see cref="GitCapabilities"/> flag to its on-the-wire
    /// protocol name (e.g. <c>"authtype"</c>).
    /// </summary>
    /// <remarks>
    /// The protocol name is always lowercase. New entries must be added here
    /// in lockstep with new <see cref="GitCapabilities"/> flag values to avoid
    /// emitting an incorrect name to Git.
    /// </remarks>
    public static string ToProtocolName(GitCapabilities capability)
    {
        // Add each flag's protocol name here as the capability is wired up.
        // The default lowercase enum name is intentionally NOT used because
        // some protocol names will not be a single token (e.g. authtype is fine
        // but a hypothetical "PasswordExpiryUtc" would have to map to a
        // protocol name distinct from its .NET enum name).
        return capability switch
        {
            GitCapabilities.State => "state",
            GitCapabilities.None => throw new ArgumentException(
                "Cannot render the None capability to a protocol name.",
                nameof(capability)),
            _ => throw new ArgumentOutOfRangeException(
                nameof(capability),
                capability,
                "No protocol name mapping is defined for the given capability."),
        };
    }

    /// <summary>
    /// Enumerate each individual <see cref="GitCapabilities"/> flag set in
    /// <paramref name="capabilities"/>, rendered to its on-the-wire protocol name.
    /// </summary>
    /// <remarks>
    /// Returns an empty sequence for <see cref="GitCapabilities.None"/>. Each
    /// emitted name comes from <see cref="ToProtocolName"/>.
    /// </remarks>
    public static IEnumerable<string> ToProtocolNames(GitCapabilities capabilities)

View on GitHub (pinned to e8ce762cd0)