When bashio::addons() is called directly and internally by other bashio functions, it throws errors or returns errant values due to its handling of default parameters.
I believe it can be fixed, but...I do not have enough knowledge to know the repercussions of fixing its behavior.
I found the bug and a workaround when writing my addon 🚧 https://github.com/diablodale/dp-ha-addons/tree/main/dp-speedtest
Setup
- RPi 4+
- HA 2025.3.4 OS on its SD card
- Local addon, built locally with default container
run.sh
#!/usr/bin/with-contenv bashio
bashio::log.level "debug"
ADDON_BUG=$(bashio::addons 'self')
bashio::log.info "Addon bug: $ADDON_BUG"
ADDON_INFO=$(bashio::addons 'self' 'addons.self.info' '.')
bashio::log.info "Addon info: $ADDON_INFO"
ADDON_SLUG=$(bashio::jq "${ADDON_INFO}" '.slug')
bashio::log.info "Addon slug: $ADDON_SLUG"
Repro
- Create a basic addon working where the Dockerfile runs
run.sh with content similar to above
- Edit
config.yaml to have only the permission homeassistant_api: true
- Install and start your addon
Result
bashio::addons 'self' fails with the error jq: error (at <stdin>:1): Cannot iterate over null (null)
[19:17:00] DEBUG: API HTTP Response code: 200
[19:17:00] DEBUG: API Response: {"result":"ok","data":{"name":"dp speedtest","slug":"local_dp-speedtest",...
jq: error (at <stdin>:1): Cannot iterate over null (null)
[19:17:00] INFO: Addon bug:
[19:17:00] INFO: Addon info: {"name":"dp speedtest","slug":"local_dp-speedtest","hostname":...
[19:17:00] INFO: Addon slug: local_dp-speedtest
Expected
No errors.
ADDON_BUG should be non-empty and have valid json.
Cause
The direct cause are lines 150 and 151. They errantly set default params that are incompatible with the result schema. They also lead to incorrect caching in some scenarios.
|
function bashio::addons() { |
|
local slug=${1:-false} |
|
local cache_key=${2:-'addons.list'} |
|
local filter=${3:-'.addons[].slug'} |
|
local info |
|
local response |
|
|
|
bashio::log.trace "${FUNCNAME[0]}" "$@" |
|
|
|
if bashio::cache.exists "${cache_key}"; then |
|
bashio::cache.get "${cache_key}" |
|
return "${__BASHIO_EXIT_OK}" |
|
fi |
|
|
|
if bashio::var.false "${slug}"; then |
|
if bashio::cache.exists "addons.list"; then |
|
info=$(bashio::cache.get 'addons.list') |
|
else |
|
info=$(bashio::api.supervisor GET "/addons" false) |
|
bashio::cache.set "addons.list" "${info}" |
|
fi |
|
else |
|
if bashio::cache.exists "addons.${slug}.info"; then |
|
info=$(bashio::cache.get "addons.${slug}.info") |
|
else |
|
info=$(bashio::api.supervisor GET "/addons/${slug}/info" false) |
|
bashio::cache.set "addons.${slug}.info" "${info}" |
|
fi |
|
fi |
|
|
|
response="${info}" |
|
if bashio::var.has_value "${filter}"; then |
|
response=$(bashio::jq "${info}" "${filter}") |
|
fi |
bashio::addons with 0 params, it calls bashio::api.supervisor GET "/addons" false and saves into cache. This supervisor call has a specific schema. It requires additional permission hassio_role: manager.
bashio::addons with 1 param, it calls bashio::api.supervisor GET "/addons/${slug}/info. This supervisor call has a different schema than 1. No additional permissions.
When the default 2nd param is applied, line 157 will retrieve+return the wrong cached value if scenario 1. has already been cached.
Line 179 has its own independent bug. It is always true since line 151 always sets a value for filter. This bug should be fixed during the fix for this issue.
When the default 3rd param is applied, line 180 will fail with jq: error (at <stdin>:1): Cannot iterate over null (null) because its 1. query does not match the data's 2. schema .
Workaround
Never call bashio::addons with 1 or 2 params.
bashio::addons 'self' 💣💥❌☠️
Always call bashio::addons with 0 or 3 params.
bashio::addons 'self' 'addons.self.info' '.' 😀👍🎉💃
When
bashio::addons()is called directly and internally by otherbashiofunctions, it throws errors or returns errant values due to its handling of default parameters.I believe it can be fixed, but...I do not have enough knowledge to know the repercussions of fixing its behavior.
I found the bug and a workaround when writing my addon 🚧 https://github.com/diablodale/dp-ha-addons/tree/main/dp-speedtest
Setup
run.sh
Repro
run.shwith content similar to aboveconfig.yamlto have only the permissionhomeassistant_api: trueResult
bashio::addons 'self'fails with the errorjq: error (at <stdin>:1): Cannot iterate over null (null)Expected
No errors.
ADDON_BUGshould be non-empty and have valid json.Cause
The direct cause are lines 150 and 151. They errantly set default params that are incompatible with the result schema. They also lead to incorrect caching in some scenarios.
bashio/lib/addons.sh
Lines 148 to 181 in d70505a
bashio::addonswith 0 params, it callsbashio::api.supervisor GET "/addons" falseand saves into cache. This supervisor call has a specific schema. It requires additional permissionhassio_role: manager.bashio::addonswith 1 param, it callsbashio::api.supervisor GET "/addons/${slug}/info. This supervisor call has a different schema than1.No additional permissions.When the default 2nd param is applied, line 157 will retrieve+return the wrong cached value if scenario
1.has already been cached.Line 179 has its own independent bug. It is always true since line 151 always sets a value for
filter. This bug should be fixed during the fix for this issue.When the default 3rd param is applied, line 180 will fail with
jq: error (at <stdin>:1): Cannot iterate over null (null)because its1.query does not match the data's2.schema .Workaround
Never call
bashio::addonswith 1 or 2 params.bashio::addons 'self'💣💥❌☠️Always call
bashio::addonswith 0 or 3 params.bashio::addons 'self' 'addons.self.info' '.'😀👍🎉💃