Bug
If AO_ALLOWED_ORIGINS is set to a value containing only commas and/or whitespace (e.g., ",,", " , , "), every piece trims to empty string and is skipped. The result is an empty AllowedOrigins slice, which silently replaces the safe default (["app://renderer"]) with nothing. The CORS middleware then rejects all cross-origin requests, including the Electron renderer's requests.
Analyzed against: 96d1649 (current main)
Confidence: High — traced through the parsing logic.
Root Cause
backend/internal/config/config.go:137-154:
func parseAllowedOrigins(raw string, defaultOrigins []string) []string {
if raw == "" {
return defaultOrigins
}
var origins []string
for _, s := range strings.Split(raw, ",") {
s = strings.TrimSpace(s)
if s == "" {
continue // skip empty pieces
}
origins = append(origins, s)
}
if len(origins) == 0 {
// BUG: returns empty slice, not defaultOrigins
return origins // ← should be: return defaultOrigins
}
return origins
}
The function checks raw == "" for the default case, but after parsing, if all pieces trimmed to empty, it returns the empty slice instead of falling back to the default.
Reproduction
AO_ALLOWED_ORIGINS=",," ao start
# Daemon starts with zero allowed origins
# Electron renderer's requests are rejected by CORS middleware
# App shows daemon-not-ready state
Impact
- Electron renderer cannot communicate with the daemon
- App is non-functional until the env var is fixed
- Silent failure: no error/warning logged about the empty origins list
Suggested Fix
After the parse loop, fall back to defaults when no valid origins were extracted:
if len(origins) == 0 {
return defaultOrigins
}
Bug
If
AO_ALLOWED_ORIGINSis set to a value containing only commas and/or whitespace (e.g.,",,"," , , "), every piece trims to empty string and is skipped. The result is an emptyAllowedOriginsslice, which silently replaces the safe default (["app://renderer"]) with nothing. The CORS middleware then rejects all cross-origin requests, including the Electron renderer's requests.Analyzed against:
96d1649(currentmain)Confidence: High — traced through the parsing logic.
Root Cause
backend/internal/config/config.go:137-154:The function checks
raw == ""for the default case, but after parsing, if all pieces trimmed to empty, it returns the empty slice instead of falling back to the default.Reproduction
Impact
Suggested Fix
After the parse loop, fall back to defaults when no valid origins were extracted: