basecamp/kamal · error · RuntimeError
Item #{item} is not a login type item and no fields were spe
Error message
Item #{item} is not a login type item and no fields were specified What it means
When a Bitwarden secret is requested as a bare item name (no "/field" suffix), the adapter falls back to the item's login.password; if the item has no login.password and no custom fields at all, it raises RuntimeError. Non-login item types (secure notes, identities, cards) hit this unless a field is specified.
Source
Thrown at lib/kamal/secrets/adapters/bitwarden.rb:38
session
end
def fetch_secrets(secrets, from:, account:, session:)
{}.tap do |results|
items_fields(prefixed_secrets(secrets, from: from)).each do |item, fields|
item_json = run_command("get item #{item.shellescape}", session: session, raw: true)
raise RuntimeError, "Could not read #{item} from Bitwarden" unless $?.success?
item_json = JSON.parse(item_json)
if fields.any?
results.merge! fetch_secrets_from_fields(fields, item, item_json)
elsif item_json.dig("login", "password")
results[item] = item_json.dig("login", "password")
elsif item_json["fields"]&.any?
fields = item_json["fields"].pluck("name")
results.merge! fetch_secrets_from_fields(fields, item, item_json)
else
raise RuntimeError, "Item #{item} is not a login type item and no fields were specified"
end
end
end
end
def fetch_secrets_from_fields(fields, item, item_json)
fields.to_h do |field|
item_field = item_json["fields"].find { |f| f["name"] == field }
raise RuntimeError, "Could not find field #{field} in item #{item} in Bitwarden" unless item_field
value = item_field["value"]
[ "#{item}/#{field}", value ]
end
end
def items_fields(secrets)
{}.tap do |items|
secrets.each do |secret|
item, field = secret.split("/")View on GitHub (pinned to eee0083b38)
Solutions
- Request the specific custom field: use my-note/fieldName (the adapter then reads item_json["fields"]) instead of the bare name
- Or convert/store the value in a login-type item so login.password fallback works
- Or add a custom field (e.g. named value) to the item and fetch item/value
Example fix
# before kamal secrets fetch -a bitwarden --account me@example.com my-api-key # item is a secure note => RuntimeError: Item my-api-key is not a login type item... # after (add a custom field "value" to the item in Bitwarden, then) kamal secrets fetch -a bitwarden --account me@example.com my-api-key/value
Defensive patterns
Strategy: validation
Validate before calling
# Non-login items must be requested with an explicit /field
name = "my-api-key"
json = JSON.parse(`bw get item #{name.shellescape}`)
abort "#{name} has no login.password and no fields — request as #{name}/<field>" if json.dig("login", "password").nil? && json["fields"].to_a.empty? Type guard
def bitwarden_bare_fetchable?(item_json)
!item_json.dig("login", "password").nil? || item_json["fields"].to_a.any?
end Try / catch
begin
adapter.fetch([name], account: account)
rescue RuntimeError => e
if e.message.include?("not a login type item")
abort "request `#{name}/<field>` instead — see `bw get item #{name}` for available fields"
end
raise
end Prevention
- Standardize on login-type items or explicit item/field refs for values fetched by kamal
- Document your vault convention (e.g. every deploy secret item has a `value` custom field) so bare fetches never hit non-login items
When it happens
Trigger: Requesting a secure-note or identity item without a field: kamal secrets fetch -a bitwarden my-note (no /field); an item whose login has an empty password; an item of unknown type with zero custom fields.
Common situations: Storing a master key or API key as a Secure Note (natural choice) instead of a login item; migrating items between types; empty placeholder items created by automation.
Related errors
- Could not read #{item} from Bitwarden
- Could not find field #{field} in item #{item} in Bitwarden
- Unknown secrets adapter: #{name}
- Failed to login to and unlock Bitwarden
- Failed to sync Bitwarden
AI-assisted analysis of basecamp/kamal@eee0083b38 (2026-08-21).
Data as JSON: /api/errors/d3fdd8614f30262d.
Report an issue: GitHub.