{"record":{"id":"084433a1c95cbbf3","repo":"git-ecosystem/git-credential-manager","slug":"1-084433","errorCode":"-1","errorMessage":"Unknown keychain search result type CFTypeID: {typeId}.","messagePattern":"Unknown keychain search result type CFTypeID: (.+?)\\.","errorType":"exception","errorClass":"InteropException","httpStatus":null,"severity":"error","filePath":"src/Core/Interop/MacOS/MacOSKeychain.cs","lineNumber":82,"sourceCode":"                {\n                    case OK:\n                        int typeId = CFGetTypeID(resultPtr);\n                        Debug.Assert(typeId == CFArrayGetTypeID(), \"Returned unknown item from account query\");\n                        if (typeId == CFArrayGetTypeID())\n                        {\n                            int len = (int)CFArrayGetCount(resultPtr);\n                            var accounts = new HashSet<string>(len);\n                            for (int i = 0; i < len; i++)\n                            {\n                                IntPtr dict = CFArrayGetValueAtIndex(resultPtr, i);\n                                string account = GetStringAttribute(dict, kSecAttrAccount);\n                                accounts.Add(account);\n                            }\n\n                            return accounts.ToList();\n                        }\n\n                        throw new InteropException($\"Unknown keychain search result type CFTypeID: {typeId}.\", -1);\n\n                    case ErrorSecItemNotFound:\n                        return Array.Empty<string>();\n\n                    default:\n                        ThrowIfError(searchResult);\n                        return null;\n                }\n            }\n            finally\n            {\n                if (query != IntPtr.Zero) CFRelease(query);\n                if (servicePtr != IntPtr.Zero) CFRelease(servicePtr);\n                if (accountPtr != IntPtr.Zero) CFRelease(accountPtr);\n                if (resultPtr != IntPtr.Zero) CFRelease(resultPtr);\n            }\n        }\n","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/git-ecosystem/git-credential-manager/blob/e8ce762cd04b4100ae637b5fbf39ef9d0a96561e/src/Core/Interop/MacOS/MacOSKeychain.cs#L64-L100","documentation":"Thrown by MacOSKeychain.GetAccounts after SecItemCopyMatching returns success but the result object is not a CFArray, which is the only type the account-listing path can process. The message embeds the unexpected CoreFoundation type ID. Because the format string uses interpolation of the raw typeId the message may literally read 'CFTypeID: {typeId}' — the code indicates an unexpected/unknown result shape from the Security framework.","triggerScenarios":"SecItemCopyMatching with kSecMatchLimitAll + kSecReturnAttributes returns OK but hands back a non-CFArray CFType (e.g. a CFDictionary on some macOS versions that return a single item instead of an array).","commonSituations":"macOS version differences in Security.framework result shapes, newer macOS deprecating legacy keychain APIs and changing SecItemCopyMatching return semantics, or corrupted/unusual keychain items causing a single-result return where an array is expected.","solutions":["Update Git Credential Manager to a version that handles single-dictionary (CFDictionary) results in GetAccounts, not just CFArray","Check the macOS version; on macOS versions with changed SecItemCopyMatching semantics, wrap the call and normalize a returned CFDictionary into a single-element list","Reproduce with a minimal SecItemCopyMatching query to log CFGetTypeID(result) and confirm what the framework returns on your OS","Report the CFTypeID value to the library maintainers with macOS version so the type can be mapped"],"exampleFix":"// before\nif (typeId == CFArrayGetTypeID()) { ... }\nthrow new InteropException($\"Unknown keychain search result type CFTypeID: {typeId}.\", -1);\n// after\nif (typeId == CFArrayGetTypeID()) { ... }\nelse if (typeId == CFDictionaryGetTypeID())\n{\n    // single result returned as a dictionary, not wrapped in an array\n    string account = GetStringAttribute(resultPtr, kSecAttrAccount);\n    return string.IsNullOrEmpty(account) ? new List<string>() : new List<string> { account };\n}\nthrow new InteropException($\"Unknown keychain search result type CFTypeID: {typeId}.\", -1);","handlingStrategy":"try-catch","validationCode":"// Pre-check the macOS version against known-supported range before using keychain accounts\nusing System;\n\nstatic bool KeychainAccountsSupported()\n{\n    // SecItemCopyMatching result-shape changed on newer macOS; require tested version\n    var v = Environment.OSVersion.Version;\n    return v.Major >= 10 && v.Minor >= 12;\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    IList<string> accounts = keychain.GetAccounts(service);\n}\ncatch (InteropException ex) when (ex.Message.Contains(\"Unknown keychain search result type CFTypeID\"))\n{\n    // Unexpected CFType returned; treat as empty account list or upgrade GCM\n    accounts = Array.Empty<string>();\n}\n","preventionTips":["Keep Git Credential Manager updated for current macOS SecItemCopyMatching semantics","Test keychain flows after every macOS upgrade (result shapes can change)","Avoid third-party tools that create anomalous keychain items for your service name","Log the CFTypeID in catch blocks to report actionable bug reports"],"tags":["macos","keychain","interop","unexpected-result-type"],"backgroundTag":"unexpected-response-shape","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"}