git-ecosystem/git-credential-manager · error · ArgumentException
A cancelled or yielded response cannot carry a credential.
Error message
A cancelled or yielded response cannot carry a credential.
What it means
GitResponse's constructor also forbids a Cancelled or Yielded response from carrying a credential: cancelling or yielding means no credential is offered to the caller, so attaching one is contradictory and throws ArgumentException with nameof(credential). A non-cancelled, non-yielded response without a credential is separately rejected.
Solutions
- Pass null for credential when the response is cancelled or yielded.
- Restructure provider code so cancellation is detected before credential acquisition, or discard the credential when returning Cancel/Yield.
- Use the static factory helpers (e.g. Cancel()) that do not accept credentials.
Example fix
// before return new GitResponse(credential, isCancelled: true); // after return new GitResponse(null, isCancelled: true); // or GitResponse.Cancel()
Defensive patterns
Strategy: validation
Validate before calling
if ((isCancelled || isYielded) && credential is not null)
throw new InvalidOperationException("Drop the credential before returning Cancel/Yield."); Type guard
bool IsValidResponse(string credential, bool cancelled, bool yielded) =>
(cancelled || yielded) ? credential is null : credential is not null; Try / catch
try
{
var response = new GitResponse(credential, isCancelled: cancelled);
}
catch (ArgumentException ex) when (ex.Message.Contains("cannot carry a credential"))
{
// return GitResponse.Cancel() without the credential instead
} Prevention
- Check for cancellation/yield conditions before acquiring a credential.
- Use GitResponse.Cancel()/Yield() factories which accept no credential.
- In tests, assert that cancel/yield responses carry null credentials.
- Keep the credential flow and the status decision as separate code paths.
When it happens
Trigger: Constructing GitResponse with isCancelled or isYielded true while passing a non-null credential object, e.g. new GitResponse(credential, isCancelled: true) from provider code that fetches a credential and then decides to cancel without dropping the credential.
Common situations: Provider implementations that obtain a credential first and later detect cancellation/yield conditions; error paths that wrap an existing credential into a cancel response; copy-paste from success-path constructors.
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
- A response can be at most one of Continue, Cancel, or Yield.
- Cannot render the None capability to a protocol name.
- Must specify at least one AuthenticationModes
- Argument cannot be empty.
- Argument cannot be empty or white space.
AI-assisted analysis of git-ecosystem/git-credential-manager@e8ce762cd0 (2026-09-11).
Data as JSON: /api/errors/e90c771a1714e926.
Report an issue: GitHub.
Appendix: source
Thrown at src/Core/GitResponse.cs:61
private readonly Dictionary<string, string> _state = new(StringComparer.Ordinal);
private ReadOnlyDictionary<string, string> _stateView;
private GitResponse(ICredential credential, bool isContinue, bool isCancelled, bool isYielded)
{
// At most one of Continue, Cancel, Yield may be set (Ok is "none of them").
if ((isContinue && isCancelled) ||
(isContinue && isYielded) ||
(isCancelled && isYielded))
{
throw new ArgumentException(
"A response can be at most one of Continue, Cancel, or Yield.");
}
bool hasCredential = credential is not null;
if ((isCancelled || isYielded) && hasCredential)
{
throw new ArgumentException(
"A cancelled or yielded response cannot carry a credential.",
nameof(credential));
}
if (!isCancelled && !isYielded && !hasCredential)
{
throw new ArgumentNullException(
nameof(credential),
"A non-cancelled, non-yielded response must carry a credential. Use Cancel() or Yield() instead.");
}
Credential = credential;
IsContinue = isContinue;
IsCancelled = isCancelled;
IsYielded = isYielded;
}
/// <summary>View on GitHub (pinned to e8ce762cd0)