fix(omo-codex): fail on unreadable config.toml instead of overwriting it (fixes #5751)#5753
Conversation
… it (fixes code-yeongyu#5751) updateCodexConfig() probed for an existing config.toml with exists(), which caught every readFile() error and returned false. A present-but-unreadable config.toml (EACCES/EPERM, or any non-ENOENT read error) was treated as absent, so the installer started from an empty config and writeFileAtomic() overwrote the user's file, dropping its contents. Read the config directly and catch only ENOENT (genuinely absent, use an empty config); re-throw every other read error before any write. The unused exists() helper is removed. Verified: new regression test goes RED (pre-fix reaches writeFileAtomic and attempts an overwrite) then GREEN (the read error is re-thrown before any write); codex-config-toml.test.ts 22 pass / 1 skip (POSIX chmod case) / 0 fail; tsgo --noEmit clean.
|
I have read the CLA Document and I hereby sign the CLA |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e4b783c555
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| try { | ||
| config = await readFile(input.configPath, "utf8") | ||
| } catch (error) { | ||
| if (!(isNodeErrorWithCode(error) && error.code === "ENOENT")) throw error |
There was a problem hiding this comment.
Regenerate the Codex installer bundle
This source-only fix is bypassed by the stable installer entrypoint in a fresh checkout: packages/omo-codex/scripts/install-local.mjs imports scripts/install-dist/install-local.mjs whenever that checked-in bundle exists, and the bundle still contains the removed if (await exists(input.configPath)) config = await readFile(...) path around its updateCodexConfig(). As a result, node packages/omo-codex/scripts/install-local.mjs install can still treat non-ENOENT read failures as an absent config and overwrite user data; run bun run build:codex-install and commit the regenerated bundle so the fix reaches the script consumers.
Useful? React with 👍 / 👎.
Summary
The omo-codex installer could overwrite an existing
config.tomlwhen the file exists but cannot be read.updateCodexConfig()now reads the config directly and only treats a genuinely-absent file (ENOENT) as empty; any other read error is re-thrown before a single byte is written.Fixes #5751.
Root Cause
updateCodexConfig()probed for an existing config with a localexists()helper:exists()swallowed everyreadFile()error and returnedfalse. A present-but-unreadableconfig.toml(EACCES/EPERM, or any non-ENOENTread failure) was therefore treated as absent, so the function started from an empty config andwriteFileAtomic()replaced the user's file, dropping its contents.Changes
packages/omo-codex/src/install/codex-config-toml.tsENOENT(use empty config), re-throw all other read errors before any write. Remove the now-unusedexists()helper. Reuses the existingisNodeErrorWithCodeguard fromcodex-cache-fs.packages/omo-codex/src/install/codex-config-toml.test.tschmod 0o200case asserting the original file is preserved.Net source change:
+6 / -9(one import, the read guard, minus the dead helper).Reproduction (before fix)
The new test against the unmodified code shows the installer reaches
writeFileAtomicand attempts to overwrite the existing path:chmodcannot make a file unreadable on Windows, so the unreadable case is exercised cross-platform via a directoryconfig.toml(soreadFilethrowsEISDIR), plus a POSIXchmod 0o200test that is skipped on Windows.Verification (after fix)
Test
packages/omo-codex/src/install/codex-config-toml.test.ts(2 new cases) - 22 pass / 1 skip (POSIX-onlychmodcase) / 0 failtsgo --noEmit -p packages/omo-codex/tsconfig.json- clean (exit 0)Fixes #5751
Summary by cubic
Prevents the
omo-codexinstaller from overwriting an existingconfig.tomlwhen the file exists but can’t be read.updateCodexConfig()now treats onlyENOENTas “missing” and fails fast on other read errors. Fixes #5751.ENOENT, re-throw all other read errors before any write.exists()probe that swallowed read errors and caused unintended overwrites.chmodto ensure the original file is preserved.Written for commit e4b783c. Summary will update on new commits.