RTL issue: multi-node configuration gets overwritten when updating application settings
Environment
Problem
In a multi-node configuration, RTL overwrites RTL-Config.json and silently removes nodes when application settings are updated from the UI.
Example:
Initial config:
"nodes": [
{
"index": 1,
"lnNode": "[alias-lnd]",
"lnImplementation": "LND"
},
{
"index": 2,
"lnNode": "[alias-cln]",
"lnImplementation": "CLN"
}
]
After opening Settings or changing application settings, the config gets rewritten containing only the currently selected node.
Depending on which node is active, the other node disappears from the config and from the UI.
This makes RTL unstable for mixed LND + CLN environments because the configuration file becomes progressively corrupted during normal UI usage.
Root cause
The issue appears to originate from updateApplicationSettings() inside:
/backend/controllers/shared/RTLConf.js
RTL rebuilds the configuration object from the frontend payload:
const config = common.addSecureData(req.body);
common.appConfig = JSON.parse(JSON.stringify(config));
The frontend payload only contains the currently selected node, so all other nodes are discarded when the config is rewritten.
Later:
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
persists the truncated configuration to disk.
Patch applied
1. Preserve existing node list
Patched updateApplicationSettings() to merge the incoming config with the previous config instead of replacing it completely.
Added:
const oldConfig = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
const config = common.addSecureData(req.body);
if (oldConfig.nodes && oldConfig.nodes.length > 0 && config.nodes && config.nodes.length > 0) {
oldConfig.nodes.forEach((oldNode) => {
if (!config.nodes.find((newNode) => newNode.index === oldNode.index)) {
config.nodes.push(oldNode);
}
});
}
Then replaced:
common.appConfig = JSON.parse(JSON.stringify(config));
with:
const mergedConfig = JSON.parse(JSON.stringify(oldConfig));
Object.keys(config).forEach((key) => {
if (key !== 'nodes') {
mergedConfig[key] = config[key];
}
});
mergedConfig.nodes = oldConfig.nodes;
common.appConfig = JSON.parse(JSON.stringify(mergedConfig));
And replaced:
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
with:
fs.writeFileSync(RTLConfFile, JSON.stringify(mergedConfig, null, 2), 'utf-8');
2. Preserve node settings during updates
Inside updateNodeSettings():
Original:
node.settings = req.body.settings;
Patched:
node.settings = { ...node.settings, ...req.body.settings };
This prevents partial frontend payloads from wiping existing settings fields.
Result after patches
- Both LND and CLN nodes persist correctly
- Node switching works
- Application settings no longer overwrite
RTL-Config.json
- Multi-node setup remains stable across UI operations
Logs now correctly show both nodes loaded simultaneously:
"nodes":[
{"index":1,"lnNode":"[alias-lnd]","lnImplementation":"LND"},
{"index":2,"lnNode":"[alias-cln]","lnImplementation":"CLN"}
]
I have identified the root cause and prepared a local fix. I will open a PR shortly.
RTL issue: multi-node configuration gets overwritten when updating application settings
Environment
RTL latest master
Node.js v22
Multi-node setup:
RTL running via systemd on Linux
Problem
In a multi-node configuration, RTL overwrites
RTL-Config.jsonand silently removes nodes when application settings are updated from the UI.Example:
Initial config:
After opening Settings or changing application settings, the config gets rewritten containing only the currently selected node.
Depending on which node is active, the other node disappears from the config and from the UI.
This makes RTL unstable for mixed LND + CLN environments because the configuration file becomes progressively corrupted during normal UI usage.
Root cause
The issue appears to originate from
updateApplicationSettings()inside:RTL rebuilds the configuration object from the frontend payload:
The frontend payload only contains the currently selected node, so all other nodes are discarded when the config is rewritten.
Later:
persists the truncated configuration to disk.
Patch applied
1. Preserve existing node list
Patched
updateApplicationSettings()to merge the incoming config with the previous config instead of replacing it completely.Added:
Then replaced:
with:
And replaced:
with:
2. Preserve node settings during updates
Inside
updateNodeSettings():Original:
Patched:
This prevents partial frontend payloads from wiping existing settings fields.
Result after patches
RTL-Config.jsonLogs now correctly show both nodes loaded simultaneously:
I have identified the root cause and prepared a local fix. I will open a PR shortly.