{"record":{"id":"04ea7fe831246bca","repo":"basecamp/kamal","slug":"key-is-present-more-than-once","errorCode":null,"errorMessage":"#{key} is present more than once","messagePattern":"#(.+?) is present more than once","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"lib/kamal/secrets/adapters/enpass.rb","lineNumber":63,"sourceCode":"        else\n          secret_titles << key\n        end\n      end.to_a\n    end\n\n    def parse_result_and_take_secrets(unparsed_result, secrets)\n      result = JSON.parse(unparsed_result)\n\n      result.reduce({}) do |secrets_with_passwords, item|\n        title = item[\"title\"]\n        label = item[\"label\"]\n        password = item[\"password\"]\n\n        if title && password.present?\n          key = [ title, label ].compact.reject(&:empty?).join(\"/\")\n\n          if secrets.include?(title) || secrets.include?(key)\n            raise RuntimeError, \"#{key} is present more than once\" if secrets_with_passwords[key]\n            secrets_with_passwords[key] = password\n          end\n        end\n\n        secrets_with_passwords\n      end\n    end\nend\n","sourceCodeStart":45,"sourceCodeEnd":72,"githubUrl":"https://github.com/basecamp/kamal/blob/eee0083b38661c3707c6b6052cc89e85038a096c/lib/kamal/secrets/adapters/enpass.rb#L45-L72","documentation":"Raised in Enpass#parse_result_and_take_secrets while folding the JSON returned by `enpass-cli -json -vault ... show ...`. Each item yields key = [title, label].compact.join('/'); when the same key appears a second time AND that key matches one of the requested secrets, kamal refuses to guess which password to use and raises. It is a duplicate-detection guard on top of an item/title/label tuple, not a general vault corruption error.","triggerScenarios":"adapter.fetch([...], from:, account:) where the vault contains two Enpass items with the same title and same (or empty) label, both with passwords, and that title (or title/label key) is in your requested secrets list; also one item exposing multiple fields with the identical label under the same title.","commonSituations":"Years-old vaults with 'Test', 'Login', or service-name duplicates created by sync/import; renaming an item but leaving a copy; items where the password lives under different fields and label collides after compact/reject of empty strings.","solutions":["Open Enpass and locate the duplicated title (search by the key shown in the error, e.g. 'API_KEY'); delete or rename the stale copy so the title is unique.","If both entries are legitimate, rename one (e.g. API_KEY_OLD) and keep the requested name unique in the vault.","If the duplicate is title-vs-label (two fields with the same label in one item), edit the item in Enpass so each labeled field is distinct, then re-run `kamal secrets pull`."],"exampleFix":"# before: vault has two items titled DB_PASSWORD\n#   kamal secrets pull  # -> \"DB_PASSWORD is present more than once\"\n\n# after: rename one item in the Enpass app\n#   DB_PASSWORD        (keep, unique)\n#   DB_PASSWORD_backup (renamed)\nkamal secrets pull","handlingStrategy":"validation","validationCode":"def unique_secret_names?(names)\n  names.tally.values.all? { |count| count == 1 }\nend\n\n# Also validate the vault side before kamal does:\nrequire \"open3\"\nout, _err, st = Open3.capture3(\"enpass-cli\", \"-json\", \"-vault\", \"Primary\", \"show\", *names)\nif st.success?\n  keys = JSON.parse(out).map { |i| [i[\"title\"], i[\"label\"]].compact.reject(&:empty?).join(\"/\") }\n  abort \"Duplicate items in vault: #{keys.group_by(&:itself).select { |_, v| v.size > 1 }.keys.join(', ')}\" unless keys.size == keys.uniq.size\nend","typeGuard":null,"tryCatchPattern":"begin\n  adapter.fetch(names, from: \"Primary\", account: nil)\nrescue RuntimeError => e\n  if e.message.end_with?(\"is present more than once\")\n    raise \"Duplicate Enpass item #{e.message}: rename the stale copy in the vault, then re-pull\"\n  end\n  raise\nend","preventionTips":["Keep one canonical item per secret title; move old values to clearly renamed backup entries.","Audit for duplicate titles after vault imports/syncs (`enpass-cli` show -json and diff on title/label keys).","Avoid reusing the same field label inside one item for multiple password fields."],"tags":["ruby","kamal","enpass","secrets","duplicate-key","data-integrity"],"backgroundTag":"duplicate-secret-key","analyzedSha":"eee0083b38661c3707c6b6052cc89e85038a096c","analyzedAt":"2026-08-21T15:17:22.045Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}