basecamp/kamal · error · RuntimeError

You must specify what to retrieve from Bitwarden Secrets…

Error message

You must specify what to retrieve from Bitwarden Secrets Manager

What it means

The Bitwarden Secrets Manager adapter (bws) fetches secrets by UUID, or lists them with `all` / `<project-id>/all` selectors. fetch_secrets raises RuntimeError when the effective secrets array is empty (after applying the --from prefix), i.e. nothing was specified to retrieve.

Solutions

  1. Pass one or more secret UUIDs: kamal secrets fetch -a bitwarden-sm <uuid1> <uuid2>
  2. Or list everything accessible: kamal secrets fetch -a bitwarden-sm all
  3. Or scope to one project: kamal secrets fetch -a bitwarden-sm <project-id>/all (or use --from <project-id> with /all)

Example fix

# before
kamal secrets fetch -a bitwarden-sm
# => RuntimeError: You must specify what to retrieve from Bitwarden Secrets Manager

# after
kamal secrets fetch -a bitwarden-sm 5c8e8d3a-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# or list all secrets the machine account can access:
kamal secrets fetch -a bitwarden-sm all
Defensive patterns

Strategy: validation

Validate before calling

secrets = ARGV.dup
secrets << "#{options[:from]}/all" if secrets.empty? && options[:from]
abort "nothing to fetch — pass secret UUIDs, `all`, or <project-id>/all" if secrets.empty?

Type guard

def bws_request_valid?(secrets, from: nil)
  (secrets + (from ? ["#{from}/all"] : [])).any? { |s| !s.to_s.strip.empty? }
end

Prevention

When it happens

Trigger: kamal secrets fetch -a bitwarden-sm with no secret arguments and no --from; passing only --from with an empty positional list that still resolves to zero secrets; programmatic adapter.fetch([], from: nil).

Common situations: Copy-pasting a fetch command and deleting the arguments while testing; scripts that interpolate a secrets list which turns out empty; misunderstanding that this adapter needs UUIDs or the all selector, not item names.

Understand the failure class

Background: "Must pass :limit option" / "Missing required option" — required option errors explained — this error's family across 41 libraries.

Related errors


AI-assisted analysis of basecamp/kamal@eee0083b38 (2026-08-21). Data as JSON: /api/errors/bb793a3d4405f7c5. Report an issue: GitHub.

Appendix: source

Thrown at lib/kamal/secrets/adapters/bitwarden_secrets_manager.rb:13

class Kamal::Secrets::Adapters::BitwardenSecretsManager < Kamal::Secrets::Adapters::Base
  def requires_account?
    false
  end

  private
    LIST_ALL_SELECTOR = "all"
    LIST_ALL_FROM_PROJECT_SUFFIX = "/all"
    LIST_COMMAND = "secret list"
    GET_COMMAND = "secret get"

    def fetch_secrets(secrets, from:, account:, session:)
      raise RuntimeError, "You must specify what to retrieve from Bitwarden Secrets Manager" if secrets.length == 0

      secrets = prefixed_secrets(secrets, from: from)
      command, project = extract_command_and_project(secrets)

      {}.tap do |results|
        if command.nil?
          secrets.each do |secret_uuid|
            item_json = run_command("#{GET_COMMAND} #{secret_uuid.shellescape}")
            raise RuntimeError, "Could not read #{secret_uuid} from Bitwarden Secrets Manager" unless $?.success?
            item_json = JSON.parse(item_json)
            results[item_json["key"]] = item_json["value"]
          end
        else
          items_json = run_command(command)
          raise RuntimeError, "Could not read secrets from Bitwarden Secrets Manager" unless $?.success?

          JSON.parse(items_json).each do |item_json|
            results[item_json["key"]] = item_json["value"]

View on GitHub (pinned to eee0083b38)