{"record":{"id":"366e85d9e53d84ff","repo":"basecamp/kamal","slug":"could-not-read-folders-from-passbolt","errorCode":null,"errorMessage":"Could not read folders from Passbolt","messagePattern":"Could not read folders from Passbolt","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"lib/kamal/secrets/adapters/passbolt.rb","lineNumber":75,"sourceCode":"      items.to_h { |item| [ item[\"name\"], item[\"password\"] ] }\n    end\n\n    def secrets_get_folders(secrets)\n      # extract all folder paths (both parent and nested)\n      folder_paths = secrets\n        .select { |s| s.include?(\"/\") }\n        .map { |s| s.split(\"/\")[0..-2] } # get all parts except the secret name\n        .uniq\n\n      return [] if folder_paths.empty?\n\n      all_folders = []\n\n      # first get all top-level folders\n      parent_folders = folder_paths.map(&:first).uniq\n      filter_condition = \"--filter '#{parent_folders.map { |name| \"Name == #{name.shellescape.inspect}\" }.join(\" || \")}'\"\n      fetch_folders = `passbolt list folders #{filter_condition} --json`\n      raise RuntimeError, \"Could not read folders from Passbolt\" unless $?.success?\n\n      parent_folder_items = JSON.parse(fetch_folders)\n      all_folders.concat(parent_folder_items)\n\n      # get nested folders for each parent\n      folder_paths.each do |path|\n        next if path.size <= 1 # skip non-nested folders\n\n        parent = path[0]\n        parent_folder = parent_folder_items.find { |f| f[\"name\"] == parent }\n        next unless parent_folder\n\n        # for each nested level, get the folders using the parent's ID\n        current_parent = parent_folder\n        path[1..-1].each do |folder_name|\n          filter_condition = \"--filter 'Name == #{folder_name.shellescape.inspect} && FolderParentID == #{current_parent[\"id\"].shellescape.inspect}'\"\n          fetch_nested = `passbolt list folders #{filter_condition} --json`\n          next unless $?.success?","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/basecamp/kamal/blob/eee0083b38661c3707c6b6052cc89e85038a096c/lib/kamal/secrets/adapters/passbolt.rb#L57-L93","documentation":"When secret references contain folder paths (e.g. passbolt/parent/nested/NAME), the adapter first resolves folders by running `passbolt list folders --filter '...' --json`. This error (passbolt.rb:75) is raised when that command exits non-zero. It is a CLI/session-level failure of the folder listing, not a 'folder does not exist' condition — genuinely missing folders produce the separate error at line 106.","triggerScenarios":"Any secrets fetch that includes at least one slash-containing passbolt reference while `passbolt list folders --filter '...' --json` fails: an unauthenticated or expired CLI session, an unreachable Passbolt server, or a filter string the CLI rejects (for example folder names containing quotes or backslashes that break the interpolated single-quoted --filter argument).","commonSituations":"The same auth/config issues as resource listing, but only hit once folder-scoped secrets are used; folder names with shell metacharacters; a passbolt CLI version whose `list folders` flags differ from what the adapter passes.","solutions":["Run `passbolt list folders --json` manually to see the CLI's own error message.","Re-authenticate or repair the CLI config (`passbolt configure`), the same as for resource read failures.","Rename folders whose names contain quotes or backslashes, or avoid referencing them from Kamal.","Check that the installed CLI version supports `list folders --filter ... --json`."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"# Preflight folder listing when any secret reference contains a slash\n`passbolt list folders --json 2>/dev/null`\nabort('Passbolt folder listing failed') unless $?.success?","typeGuard":null,"tryCatchPattern":"begin\n  # task resolving passbolt/folder/... secrets\nrescue RuntimeError => e\n  if e.message =~ /Could not read folders from Passbolt/\n    abort \"#{e.message} — diagnose with: passbolt list folders --json\"\n  else\n    raise\n  end\nend","preventionTips":["Preflight `passbolt list folders --json` in CI when folder-scoped secrets are used","Avoid quotes and backslashes in Passbolt folder names","Re-run `passbolt configure` after key or server changes"],"tags":["passbolt","kamal","folders","cli","process-exit"],"backgroundTag":"cli-command-failed","analyzedSha":"eee0083b38661c3707c6b6052cc89e85038a096c","analyzedAt":"2026-08-21T15:17:22.045Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}