{"record":{"id":"e90c771a1714e926","repo":"git-ecosystem/git-credential-manager","slug":"a-cancelled-or-yielded-response-cannot-carry-a-cre","errorCode":null,"errorMessage":"A cancelled or yielded response cannot carry a credential.","messagePattern":"A cancelled or yielded response cannot carry a credential\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Core/GitResponse.cs","lineNumber":61,"sourceCode":"    private readonly Dictionary<string, string> _state = new(StringComparer.Ordinal);\n    private ReadOnlyDictionary<string, string> _stateView;\n\n    private GitResponse(ICredential credential, bool isContinue, bool isCancelled, bool isYielded)\n    {\n        // At most one of Continue, Cancel, Yield may be set (Ok is \"none of them\").\n        if ((isContinue && isCancelled) ||\n            (isContinue && isYielded) ||\n            (isCancelled && isYielded))\n        {\n            throw new ArgumentException(\n                \"A response can be at most one of Continue, Cancel, or Yield.\");\n        }\n\n        bool hasCredential = credential is not null;\n\n        if ((isCancelled || isYielded) && hasCredential)\n        {\n            throw new ArgumentException(\n                \"A cancelled or yielded response cannot carry a credential.\",\n                nameof(credential));\n        }\n\n        if (!isCancelled && !isYielded && !hasCredential)\n        {\n            throw new ArgumentNullException(\n                nameof(credential),\n                \"A non-cancelled, non-yielded response must carry a credential. Use Cancel() or Yield() instead.\");\n        }\n\n        Credential = credential;\n        IsContinue = isContinue;\n        IsCancelled = isCancelled;\n        IsYielded = isYielded;\n    }\n\n    /// <summary>","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/git-ecosystem/git-credential-manager/blob/e8ce762cd04b4100ae637b5fbf39ef9d0a96561e/src/Core/GitResponse.cs#L43-L79","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nreturn new GitResponse(credential, isCancelled: true);\n// after\nreturn new GitResponse(null, isCancelled: true); // or GitResponse.Cancel()","handlingStrategy":"validation","validationCode":"if ((isCancelled || isYielded) && credential is not null)\n    throw new InvalidOperationException(\"Drop the credential before returning Cancel/Yield.\");","typeGuard":"bool IsValidResponse(string credential, bool cancelled, bool yielded) =>\n    (cancelled || yielded) ? credential is null : credential is not null;","tryCatchPattern":"try\n{\n    var response = new GitResponse(credential, isCancelled: cancelled);\n}\ncatch (ArgumentException ex) when (ex.Message.Contains(\"cannot carry a credential\"))\n{\n    // return GitResponse.Cancel() without the credential instead\n}","preventionTips":["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."],"tags":["git-protocol","response-validation","credential","argument-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"e8ce762cd04b4100ae637b5fbf39ef9d0a96561e","analyzedAt":"2026-09-11T17:15:08.753Z","contentChangedAt":"2026-09-11T17:15:08.753Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}