{"record":{"id":"e6e8ef4d1b9a125c","repo":"dagger/dagger","slug":"item-s-is-locked","errorCode":null,"errorMessage":"item %s is locked","messagePattern":"item (.+?) is locked","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/client/secretprovider/libsecret.go","lineNumber":77,"sourceCode":"\n\t// get all items\n\titems, err := collection.Items()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(items) == 0 {\n\t\treturn nil, fmt.Errorf(\"no items found in collection %s\", uri.Hostname())\n\t}\n\tfor _, item := range items {\n\t\tlocked, err := item.Locked()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif locked {\n\t\t\t// something has gone *wrong* - we've just called Unlock on the\n\t\t\t// collection, so nothing should be locked (but this does seem to\n\t\t\t// happen, Unlock doesn't seem to always return an error on failure)\n\t\t\treturn nil, fmt.Errorf(\"item %s is locked\", item.Path())\n\t\t}\n\t}\n\n\t// filter items using the path\n\tvar matching []libsecret.Item\n\tif uri.Path == \"\" {\n\t\t// path is empty, just grab all\n\t\t// libsecret://<collection>\n\t\tmatching = items\n\t\tif len(uri.Query()) == 0 {\n\t\t\treturn nil, fmt.Errorf(\"item %s must be filtered\", key)\n\t\t}\n\t}\n\tif matching == nil {\n\t\tfor _, candidate := range items {\n\t\t\tname := path.Base(string(candidate.Path()))\n\t\t\tif name == uri.Path {\n\t\t\t\t// path contains an auto-generated item specific identifier","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/dagger/dagger/blob/82ba2681dbe30d3547a1dc50ea495900ab5b6047/engine/client/secretprovider/libsecret.go#L59-L95","documentation":"The provider calls svc.Unlock(collection) and then checks each item's Locked() state. If an item is still locked after unlocking the collection, Unlock silently failed (a known quirk — Unlock doesn't always return an error on failure), so the provider throws this error rather than reading the secret.","triggerScenarios":"libsecret://<collection>/... where the collection's Unlock triggered a prompt that was dismissed, timed out, or could not be shown (headless session), leaving items locked.","commonSituations":"Headless CI/container environments with no prompt agent to answer the keyring unlock dialog; user cancelled the GNOME unlock prompt; PAM auto-unlock not configured; KeePassXC database locked.","solutions":["Unlock the keyring beforehand (normal login with PAM auto-unlock, or secret-tool unlock).","In headless environments, pre-unlock at session start via gnome-keyring-daemon --unlock with the keyring password.","If using KeePassXC, open and unlock the database.","Re-run and accept the unlock prompt when it appears."],"exampleFix":"// before (headless CI: prompt cannot appear)\n$ dagger query  # -> item .../item1 is locked\n// after (CI setup step)\necho -n \"$KEYRING_PASS\" | gnome-keyring-daemon --unlock --replace","handlingStrategy":"try-catch","validationCode":"// pre-flight: ensure the collection's items are unlocked\nsvc, _ := libsecret.NewService()\ncoll, _ := findCollection(svc, name)\nitems, _ := coll.Items()\nfor _, it := range items {\n\tlocked, _ := it.Locked()\n\tif locked {\n\t\t_ = svc.Unlock(coll) // resolve prompts before the real lookup\n\t}\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"is locked\") {\n\treturn fmt.Errorf(\"keyring still locked — unlock it (PAM login, secret-tool unlock, or gnome-keyring-daemon --unlock) and retry: %w\", err)\n}","preventionTips":["Configure PAM gnome-keyring auto-unlock so the login keyring opens at login.","In headless/CI, unlock the daemon explicitly with a password piped to gnome-keyring-daemon --unlock.","Don't dismiss the unlock prompt; unlock before running Dagger."],"tags":["libsecret","gnome-keyring","locked","headless","secret-service"],"backgroundTag":"keyring-locked","analyzedSha":"82ba2681dbe30d3547a1dc50ea495900ab5b6047","analyzedAt":"2026-09-05T07:21:37.930Z","contentChangedAt":"2026-09-05T07:21:37.930Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}