From af7733f89f4793a437c87df6ca33ff9e22fdae1a Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Wed, 11 Feb 2026 00:44:45 +0900 Subject: [PATCH] fix(config-migration): always apply migration in-memory and track backup success Migration changes were only applied to rawConfig if file write succeeded, leaving the running process on stale config. Also stops logging backup path when the backup copy itself failed. --- src/shared/migration/config-migration.ts | 39 ++++++++++++++---------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/shared/migration/config-migration.ts b/src/shared/migration/config-migration.ts index 4a0bdefc..b3051efb 100644 --- a/src/shared/migration/config-migration.ts +++ b/src/shared/migration/config-migration.ts @@ -8,7 +8,6 @@ export function migrateConfigFile( configPath: string, rawConfig: Record ): boolean { - // Work on a deep copy — only apply changes to rawConfig if file write succeeds const copy = structuredClone(rawConfig) let needsWrite = false @@ -98,28 +97,36 @@ export function migrateConfigFile( } if (needsWrite) { + const timestamp = new Date().toISOString().replace(/[:.]/g, "-") + const backupPath = `${configPath}.bak.${timestamp}` + let backupSucceeded = false try { - const timestamp = new Date().toISOString().replace(/[:.]/g, "-") - const backupPath = `${configPath}.bak.${timestamp}` - try { - fs.copyFileSync(configPath, backupPath) - } catch { - // Original file may not exist yet — skip backup - } - - fs.writeFileSync(configPath, JSON.stringify(copy, null, 2) + "\n", "utf-8") - log(`Migrated config file: ${configPath} (backup: ${backupPath})`) - } catch (err) { - log(`Failed to write migrated config to ${configPath}:`, err) - // File write failed — rawConfig is untouched, preserving user's original values - return false + fs.copyFileSync(configPath, backupPath) + backupSucceeded = true + } catch { + // Original file may not exist yet — skip backup + } + + let writeSucceeded = false + try { + fs.writeFileSync(configPath, JSON.stringify(copy, null, 2) + "\n", "utf-8") + writeSucceeded = true + } catch (err) { + log(`Failed to write migrated config to ${configPath}:`, err) } - // File write succeeded — apply changes to the original rawConfig for (const key of Object.keys(rawConfig)) { delete rawConfig[key] } Object.assign(rawConfig, copy) + + if (writeSucceeded) { + const backupMessage = backupSucceeded ? ` (backup: ${backupPath})` : "" + log(`Migrated config file: ${configPath}${backupMessage}`) + } else { + const backupMessage = backupSucceeded ? ` (backup: ${backupPath})` : "" + log(`Applied migrated config in-memory for: ${configPath}${backupMessage}`) + } } return needsWrite