{"record":{"id":"09b7e0225b563c73","repo":"git-ecosystem/git-credential-manager","slug":"failed-to-unlock-item","errorCode":null,"errorMessage":"Failed to unlock item","messagePattern":"Failed to unlock item","errorType":"exception","errorClass":"InteropException","httpStatus":null,"severity":"error","filePath":"src/Core/Interop/Linux/SecretServiceCollection.cs","lineNumber":111,"sourceCode":"                    {\r\n                        var toUnlockList = new GList\r\n                        {\r\n                            data = (IntPtr) item,\r\n                            next = IntPtr.Zero,\r\n                            prev = IntPtr.Zero\r\n                        };\r\n\r\n                        int numUnlocked = secret_service_unlock_sync(\r\n                            secService,\r\n                            &toUnlockList,\r\n                            IntPtr.Zero,\r\n                            out _,\r\n                            out error\r\n                        );\r\n\r\n                        if (numUnlocked != 1)\r\n                        {\r\n                            throw new InteropException(\"Failed to unlock item\", numUnlocked);\r\n                        }\r\n                    }\r\n\r\n                    credentials.Add(CreateCredentialFromItem(item));\r\n\r\n                    itemPtr = (GList*)itemPtr->next;\r\n                }\r\n\r\n                return credentials;\r\n            }\r\n            finally\r\n            {\r\n                if (queryAttrs != null) g_hash_table_destroy(queryAttrs);\r\n                if (error != null) g_error_free(error);\r\n                if (results != null) g_list_free_full(results, g_object_unref);\r\n            }\r\n        }\r\n\r","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/git-ecosystem/git-credential-manager/blob/e8ce762cd04b4100ae637b5fbf39ef9d0a96561e/src/Core/Interop/Linux/SecretServiceCollection.cs#L93-L129","documentation":"During Enumerate, each locked item found by the search is unlocked with secret_item_unlock_sync; if the call does not unlock exactly one item (numUnlocked != 1), an InteropException is thrown because the credential's secret cannot be read while the item remains locked.","triggerScenarios":"GetAccounts() or Get() iterating items whose collection is locked, and the unlock prompt is cancelled, times out, or returns a count other than 1 (e.g. 0 unlocked).","commonSituations":"Headless/session-less environments where no unlock prompt UI can appear; user dismisses the keyring password prompt; keyring password changed or unknown.","solutions":["Unlock the keyring beforehand (login to the desktop session or run seahorse and unlock 'Default keyring')","Ensure a prompter is available: run within a session that can show the unlock dialog, or pre-unlock via gnome-keyring-daemon --unlock","Catch InteropException and treat locked items as inaccessible rather than aborting enumeration","Check the numUnlocked value in the exception code to distinguish 0 unlocked from other counts"],"exampleFix":"// before\nvar cred = collection.Get(\"myapp\", \"user\"); // throws while keyring locked\n// after\nUnlockKeyringViaPrompt(); // e.g. gnome-keyring-daemon --unlock or seahorse\nvar cred = collection.Get(\"myapp\", \"user\");","handlingStrategy":"try-catch","validationCode":"// Cannot query lock state via this API; ensure session can prompt:\nbool CanPrompt() => Environment.UserInteractive && Environment.GetEnvironmentVariable(\"DISPLAY\") != null;","typeGuard":null,"tryCatchPattern":"try { return collection.Get(key); }\ncatch (InteropException ex) when (ex.Message == \"Failed to unlock item\") { PromptUserToUnlockKeyring(); return collection.Get(key); }","preventionTips":["Unlock the default keyring at session login","Avoid enumerating keyring credentials in headless sessions where prompts cannot appear","Pre-unlock via gnome-keyring-daemon --unlock in scripts/CI","Handle the case where a user cancels the unlock dialog"],"tags":["linux","keyring","locked","dbus"],"backgroundTag":"permission-denied","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"}