Summary
After upgrading to v1.0.1, manual runs triggered from the web UI fail Subsonic
authentication with Wrong username or password, even when the same credentials
worked previously (pre-1.0.0 via docker-compose env vars).
Root cause: passwords containing $ followed by an uppercase letter, digit, or
underscore get partially eaten when the .env file is parsed, because the wizard
writes the value to disk un-quoted. Confirmed by changing password to not have any
special characters. Also confirmed that if I wrap the password in single quotes it works
as expected.
Reproduction
- Set up Explo v1.0.0 with the web UI enabled.
- In the wizard's media-system step, enter a Subsonic/Navidrome password that
contains $ followed by A-Z, 0-9, or _ (e.g. pa$$Word1, foo$BAR,
secret$1).
- Trigger a manual run from the UI.
- Logs show:
WARN SearchPlaylist failed: Wrong username or password
WARN SearchSongs failed: Wrong username or password
WARN [subsonic] failed to schedule a library scan: Wrong username or password
I should note that the issue mentions SYSTEM_PASSWORD, but this would be an issue for any env variable that has this pattern.
I'm not strong in go, so below is what claude thinks the problem is (which for the record sounds like a reasonable assessment to me)
Root cause
updateEnvKeys in src/web/backend/server.go:451-501 writes each env value
verbatim:
lines[i] = key + "=" + val
No quoting or escaping is applied. cleanenv.ReadConfig (in
src/config/config.go:184) then parses the file with joho/godotenv, which
runs every unquoted value through expandVariables. Its regex —
(\\)?(\$)(\()?\{?([A-Z0-9_]+)?\}?
— expands any $ followed by [A-Z0-9_]+ as a variable reference, silently
replacing it with the empty string when the referenced var is unset.
Verified directly against godotenv@v1.5.1:
Raw .env value |
Parsed result |
abc$^!*xyz |
abc$^!*xyz (ok) |
p$assword |
p$assword (ok) |
p$ASSWORD |
p (mangled) |
'p$ASSWORD' |
p$ASSWORD (ok — single quotes disable expansion) |
"p$ASSWORD" |
p (still expanded — double quotes don't help) |
Pre-1.0.0 deployments commonly set SYSTEM_PASSWORD via docker-compose
environment: blocks, which bypass godotenv entirely — that's why this only
surfaces after migrating to the wizard-generated .env.
The same bug affects any field with these characters: SYSTEM_PASSWORD,
API_KEY, SLSKD_API_KEY, YOUTUBE_API_KEY, UI_PASSWORD, MATRIX_ACCESSTOKEN,
DISCORD_BOT_TOKEN, etc.
Workaround
Manually edit /opt/explo/.env and wrap affected values in single quotes:
SYSTEM_PASSWORD='my$Real$Password'
Double quotes don't work — godotenv still expands $VAR inside them.
Suggested fix
In updateEnvKeys (src/web/backend/server.go:476), single-quote values that
contain any of: $, #, ", leading/trailing whitespace, or newlines, and
escape embedded single quotes. Re-saving via the wizard should round-trip
existing values safely.
Environment
- Explo v1.0.1
- Music system: Navidrome (Subsonic API)
- Deployment: Docker, web UI enabled
- Config written by the v1.0.0 setup wizard
Summary
After upgrading to v1.0.1, manual runs triggered from the web UI fail Subsonic
authentication with
Wrong username or password, even when the same credentialsworked previously (pre-1.0.0 via docker-compose env vars).
Root cause: passwords containing
$followed by an uppercase letter, digit, orunderscore get partially eaten when the
.envfile is parsed, because the wizardwrites the value to disk un-quoted. Confirmed by changing password to not have any
special characters. Also confirmed that if I wrap the password in single quotes it works
as expected.
Reproduction
contains
$followed byA-Z,0-9, or_(e.g.pa$$Word1,foo$BAR,secret$1).I should note that the issue mentions
SYSTEM_PASSWORD, but this would be an issue for any env variable that has this pattern.I'm not strong in go, so below is what claude thinks the problem is (which for the record sounds like a reasonable assessment to me)
Root cause
updateEnvKeysinsrc/web/backend/server.go:451-501writes each env valueverbatim:
No quoting or escaping is applied.
cleanenv.ReadConfig(insrc/config/config.go:184) then parses the file withjoho/godotenv, whichruns every unquoted value through
expandVariables. Its regex —— expands any
$followed by[A-Z0-9_]+as a variable reference, silentlyreplacing it with the empty string when the referenced var is unset.
Verified directly against
godotenv@v1.5.1:.envvalueabc$^!*xyzabc$^!*xyz(ok)p$asswordp$assword(ok)p$ASSWORDp(mangled)'p$ASSWORD'p$ASSWORD(ok — single quotes disable expansion)"p$ASSWORD"p(still expanded — double quotes don't help)Pre-1.0.0 deployments commonly set
SYSTEM_PASSWORDvia docker-composeenvironment:blocks, which bypass godotenv entirely — that's why this onlysurfaces after migrating to the wizard-generated
.env.The same bug affects any field with these characters:
SYSTEM_PASSWORD,API_KEY,SLSKD_API_KEY,YOUTUBE_API_KEY,UI_PASSWORD,MATRIX_ACCESSTOKEN,DISCORD_BOT_TOKEN, etc.Workaround
Manually edit
/opt/explo/.envand wrap affected values in single quotes:Double quotes don't work — godotenv still expands
$VARinside them.Suggested fix
In
updateEnvKeys(src/web/backend/server.go:476), single-quote values thatcontain any of:
$,#,", leading/trailing whitespace, or newlines, andescape embedded single quotes. Re-saving via the wizard should round-trip
existing values safely.
Environment