Environment
MagicMirror² version: v2.37.0
Git revision: 4b4a595
Node version: 24.20.0
npm version: 11.19.0
System:
- Raspberry Pi 4 Model B Rev 1.5
- Debian GNU/Linux 13 (trixie)
- Architecture: arm64
- Kernel: 6.18.39+rpt-rpi-v8
- Time zone: Europe/Berlin
MagicMirror system information:
- MM: version: v2.37.0; git: 4b4a595; branch: HEAD
- SYSTEM: manufacturer: Raspberry Pi Foundation; model: Raspberry Pi 4 Model B Rev 1.5; virtual: false
- OS: platform: linux; distro: Debian GNU/Linux; release: 13; arch: arm64; kernel: 6.18.39+rpt-rpi-v8
- VERSIONS: electron: undefined; used node: 24.20.0; installed node: 24.20.0; npm: 11.19.0; pm2:
- ENV: XDG_SESSION_TYPE: tty; MM_CONFIG_FILE: undefined
WAYLAND_DISPLAY: undefined; DISPLAY: undefined; ELECTRON_ENABLE_GPU: undefined
- OTHERS: timeZone: Europe/Berlin
Which start option are you using?
node --run server
Are you using PM2?
No
Module
calendar
Have you tried disabling other modules?
Have you searched if someone else has already reported the issue on the forum or in the issues?
What did you do?
I reproduced the issue with a minimal configuration containing only two
instances of the default calendar module.
hideConfigSecrets is enabled and each calendar instance uses a different
SECRET_* variable.
Both secret variables intentionally contain exactly the same public ICS URL.
This removes the calendar source itself as a possible cause.
config.env
SECRET_CAL_FAMILIE="https://i.cal.to/ical/2699/bundesliga/bundesliga-gesamtspielplan/de/9d128a30.2a24b9b2-b9870bf4.ics"
SECRET_CAL_KIND="https://i.cal.to/ical/2699/bundesliga/bundesliga-gesamtspielplan/de/9d128a30.2a24b9b2-b9870bf4.ics"
Test A
Minimal config.js:
const config = {
address: "0.0.0.0",
port: 8080,
basePath: "/",
hideConfigSecrets: true,
modules: [
{
module: "calendar",
position: "top_left",
config: {
calendars: [
{
name: "Familie",
url: "${SECRET_CAL_FAMILIE}"
}
]
}
},
{
module: "calendar",
position: "top_right",
config: {
calendars: [
{
name: "Kind",
url: "${SECRET_CAL_KIND}"
}
]
}
}
]
};
if (typeof module !== "undefined") {
module.exports = config;
}
Before starting MagicMirror I checked the configuration with:
The result was:
Your configuration file doesn't contain syntax errors :)
Your modules structure configuration doesn't contain errors :)
I then started MagicMirror with:
Result:
SECRET_CAL_FAMILIE, which is referenced by the first calendar
instance, is resolved successfully.
SECRET_CAL_KIND, which is referenced only by the second instance,
remains masked as **SECRET_CAL_KIND**.
The second instance fails with:
[ERROR] [calendar] Malformed calendar url: **SECRET_CAL_KIND** TypeError: Invalid URL
...
code: 'ERR_INVALID_URL',
input: '**SECRET_CAL_KIND**'
At the same time the other calendar is fetched successfully:
[calendar] Create new calendarfetcher for url: https://i.cal.to/ical/2699/bundesliga/bundesliga-gesamtspielplan/de/9d128a30.2a24b9b2-b9870bf4.ics - Interval: 3600000
[calendar] Broadcasting 94 events from https://i.cal.to/ical/2699/bundesliga/bundesliga-gesamtspielplan/de/9d128a30.2a24b9b2-b9870bf4.ics.
Test B - reverse order
I then changed only the order of the two calendar instances:
modules: [
{
module: "calendar",
position: "top_left",
config: {
calendars: [
{
name: "Kind",
url: "${SECRET_CAL_KIND}"
}
]
}
},
{
module: "calendar",
position: "top_right",
config: {
calendars: [
{
name: "Familie",
url: "${SECRET_CAL_FAMILIE}"
}
]
}
}
]
Again I ran:
with no configuration errors, followed by:
The result was now reversed:
SECRET_CAL_KIND, now referenced by the first instance, works.
SECRET_CAL_FAMILIE, now referenced only by the second instance,
remains masked and fails.
The error is:
[ERROR] [calendar] Malformed calendar url: **SECRET_CAL_FAMILIE** TypeError: Invalid URL
...
code: 'ERR_INVALID_URL',
input: '**SECRET_CAL_FAMILIE**'
The other calendar again loads successfully:
[calendar] Create new calendarfetcher for url: https://i.cal.to/ical/2699/bundesliga/bundesliga-gesamtspielplan/de/9d128a30.2a24b9b2-b9870bf4.ics - Interval: 3600000
[calendar] Broadcasting 94 events from https://i.cal.to/ical/2699/bundesliga/bundesliga-gesamtspielplan/de/9d128a30.2a24b9b2-b9870bf4.ics.
No other modules were enabled during either test.
What did you expect to happen?
Each instance of the same module should be able to use its own SECRET_*
variables when hideConfigSecrets: true is enabled.
Both calendar instances should resolve their respective secret URL
server-side and successfully load the calendar.
What actually happened?
Only the secret referenced by the first instance of the calendar module
is resolved successfully.
A different secret that is referenced only by a subsequent instance remains
masked and is passed to the calendar node helper as its masked placeholder,
for example:
This causes:
TypeError: Invalid URL
code: 'ERR_INVALID_URL'
Reversing only the order of the two module instances also reverses which
secret works:
Test A:
- first instance:
SECRET_CAL_FAMILIE -> works
- second instance:
SECRET_CAL_KIND -> remains masked and fails
Test B:
- first instance:
SECRET_CAL_KIND -> works
- second instance:
SECRET_CAL_FAMILIE -> remains masked and fails
Both secrets contain exactly the same public ICS URL.
The failure therefore follows the module instance order, not the secret
variable name or the calendar URL.
Additional comments
The issue is reproducible with a minimal configuration containing only two
instances of the default calendar module.
node --run config:check reports no syntax or module structure errors for
either test configuration.
Both SECRET_* variables intentionally point to exactly the same public
ICS URL.
A single secret used by the first module instance is expanded correctly.
A different secret used only by the second instance remains masked.
Changing only the module instance order changes which secret fails.
This suggests that the set of secrets allowed for server-side expansion may
currently be derived from only the first configuration instance of a module,
instead of from all configured instances of that module.
The tests above demonstrate the observable behavior only; I have not
confirmed the underlying implementation cause.
Participation
Environment
MagicMirror² version: v2.37.0
Git revision: 4b4a595
Node version: 24.20.0
npm version: 11.19.0
System:
MagicMirror system information:
WAYLAND_DISPLAY: undefined; DISPLAY: undefined; ELECTRON_ENABLE_GPU: undefined
Which start option are you using?
node --run server
Are you using PM2?
No
Module
calendar
Have you tried disabling other modules?
Have you searched if someone else has already reported the issue on the forum or in the issues?
What did you do?
I reproduced the issue with a minimal configuration containing only two
instances of the default
calendarmodule.hideConfigSecretsis enabled and each calendar instance uses a differentSECRET_*variable.Both secret variables intentionally contain exactly the same public ICS URL.
This removes the calendar source itself as a possible cause.
config.env
Test A
Minimal
config.js:Before starting MagicMirror I checked the configuration with:
The result was:
I then started MagicMirror with:
Result:
SECRET_CAL_FAMILIE, which is referenced by the firstcalendarinstance, is resolved successfully.
SECRET_CAL_KIND, which is referenced only by the second instance,remains masked as
**SECRET_CAL_KIND**.The second instance fails with:
At the same time the other calendar is fetched successfully:
Test B - reverse order
I then changed only the order of the two
calendarinstances:Again I ran:
with no configuration errors, followed by:
The result was now reversed:
SECRET_CAL_KIND, now referenced by the first instance, works.SECRET_CAL_FAMILIE, now referenced only by the second instance,remains masked and fails.
The error is:
The other calendar again loads successfully:
No other modules were enabled during either test.
What did you expect to happen?
Each instance of the same module should be able to use its own
SECRET_*variables when
hideConfigSecrets: trueis enabled.Both
calendarinstances should resolve their respective secret URLserver-side and successfully load the calendar.
What actually happened?
Only the secret referenced by the first instance of the
calendarmoduleis resolved successfully.
A different secret that is referenced only by a subsequent instance remains
masked and is passed to the calendar node helper as its masked placeholder,
for example:
This causes:
Reversing only the order of the two module instances also reverses which
secret works:
Test A:
SECRET_CAL_FAMILIE-> worksSECRET_CAL_KIND-> remains masked and failsTest B:
SECRET_CAL_KIND-> worksSECRET_CAL_FAMILIE-> remains masked and failsBoth secrets contain exactly the same public ICS URL.
The failure therefore follows the module instance order, not the secret
variable name or the calendar URL.
Additional comments
The issue is reproducible with a minimal configuration containing only two
instances of the default
calendarmodule.node --run config:checkreports no syntax or module structure errors foreither test configuration.
Both
SECRET_*variables intentionally point to exactly the same publicICS URL.
A single secret used by the first module instance is expanded correctly.
A different secret used only by the second instance remains masked.
Changing only the module instance order changes which secret fails.
This suggests that the set of secrets allowed for server-side expansion may
currently be derived from only the first configuration instance of a module,
instead of from all configured instances of that module.
The tests above demonstrate the observable behavior only; I have not
confirmed the underlying implementation cause.
Participation