Problem
loadConfigFile() returns defaults after any parse/read error. A later settings change saves that default object over the original config, losing the user's settings and the only copy of the malformed file.
Reproduction (built from current main, b037891)
In a temporary AETHER_CONFIG_DIR, write config.json as { invalid json, then run:
aether config set defaultEffort high
It prints defaultEffort → HIGH, exits 0, and replaces config.json with a full default config. The original bytes are gone. This can also reset a custom baseUrl to the production endpoint without a visible warning.
Relevant code: src/core/config.ts (loadConfigFile, saveConfig) and src/commands/config.ts (set).
Expected
Read-only CLI use may fall back to defaults, but mutation should not silently overwrite an unreadable/corrupt config. Either stop with a clear repair message or preserve the exact original bytes in a backup before writing repaired settings. Add a CLI-level regression test for config set on malformed JSON.
Problem
loadConfigFile()returns defaults after any parse/read error. A later settings change saves that default object over the original config, losing the user's settings and the only copy of the malformed file.Reproduction (built from current
main,b037891)In a temporary
AETHER_CONFIG_DIR, writeconfig.jsonas{ invalid json, then run:It prints
defaultEffort → HIGH, exits 0, and replacesconfig.jsonwith a full default config. The original bytes are gone. This can also reset a custombaseUrlto the production endpoint without a visible warning.Relevant code:
src/core/config.ts(loadConfigFile,saveConfig) andsrc/commands/config.ts(set).Expected
Read-only CLI use may fall back to defaults, but mutation should not silently overwrite an unreadable/corrupt config. Either stop with a clear repair message or preserve the exact original bytes in a backup before writing repaired settings. Add a CLI-level regression test for
config seton malformed JSON.