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

State key cannot contain '=', newline, or NUL characters.

Error message

State key cannot contain '=', newline, or NUL characters.

What it means

State entries are serialized as 'key=value' lines terminated by newlines in the credential-helper protocol. Characters '=', LF, or NUL inside a key would corrupt that framing, so ValidateKey rejects them with ArgumentException.

Solutions

  1. Sanitize/encode the key before use, e.g. percent-encode or strip forbidden characters.
  2. Keep state keys to a restricted alphabet (alphanumerics, '-', '_').
  3. Replace '=' inside the key with a safe separator if a composite key is needed.

Example fix

// before
response.SetState($"provider={providerName}", value);
// after
response.SetState($"provider-{providerName.Replace('=', '_')}", value);
Defensive patterns

Strategy: validation

Validate before calling

bool ok = key != null && key.IndexOfAny(new[] {'=', '\n', '\r', '\0'}) < 0;

Type guard

static bool IsWireSafeKey(string k) => !string.IsNullOrEmpty(k) && !k.Any(c => c == '=' || c == '\n' || c == '\0');

Try / catch

try { response.SetState(key, value); }
catch (ArgumentException e) when (e.Message.Contains("cannot contain")) { key = Sanitize(key); response.SetState(key, value); }

Prevention

When it happens

Trigger: Calling SetState/WithState with a key containing '=', a newline ('\n' or '\r\n'), or a NUL byte ('\0').

Common situations: Deriving state keys from URLs, error messages, or user data that can embed '=' or line breaks; concatenating key parts without sanitization.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at src/Core/GitStateValidation.cs:90

        return true;
    }

    /// <summary>
    /// Throws <see cref="ArgumentException"/> if <paramref name="key"/> is not
    /// a legal state entry key.
    /// </summary>
    public static void ValidateKey(string key)
    {
        if (string.IsNullOrWhiteSpace(key))
        {
            throw new ArgumentException("State key cannot be null or whitespace.", nameof(key));
        }

        foreach (char c in key)
        {
            if (c == EQ || c == LF || c == NUL)
            {
                throw new ArgumentException(
                    "State key cannot contain '=', newline, or NUL characters.",
                    nameof(key));
            }
        }

        if (key.StartsWith(Constants.CredentialProtocol.GcmStatePrefix, StringComparison.Ordinal))
        {
            throw new ArgumentException(
                $"State key cannot start with '{Constants.CredentialProtocol.GcmStatePrefix}'; " +
                "the prefix is reserved and added automatically when state is emitted.",
                nameof(key));
        }
    }

    /// <summary>
    /// Throws <see cref="ArgumentException"/> if <paramref name="value"/> is
    /// not a legal state entry value.
    /// </summary>

View on GitHub (pinned to e8ce762cd0)