basecamp/kamal · error · RuntimeError

You must specify what to retrieve from Bitwarden Secrets Man

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.

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)

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.

Related errors


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