HarperFast / HarperFast/harper
set_configuration can silently no-op and still return success (updateConfigValue never refreshes flatConfigObj)
- Dominant language
- JavaScript
- Stars
- 89
- Forks
- 10
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 200
Description
## Summary
`set_configuration` can skip a write entirely and still return success. `updateConfigValue` never refreshes `flatConfigObj` after writing (`update_config_obj` defaults to `false`), so the comparison that decides whether a write is needed is made against the **boot-time cached** value rather than what is currently on disk.
When the on-disk value has diverged from that cache, setting the key back to the cached value is treated as a no-op — and the caller is told it succeeded.
## How the cache diverges from disk
Two ordinary paths, neither of them exotic:
1. **An out-of-band edit.** Someone edits `harper-config.yaml` directly, or another process writes it. The cache still holds the boot-time value.
2. **An earlier `set_configuration` in the same process lifetime.** The first call writes to disk but doesn't refresh the cache, so every later call compares against a value that is now stale by exactly the amount the first call changed.
The second is the more troubling one, because it needs no external actor: a sequence of `set_configuration` calls in one process can silently drop any call that returns a key to its boot-time value.
## Why it matters
The failure is indistinguishable from success at the API boundary — same response, nothing logged. An operator confirming a setting gets told the setting is applied. This was found precisely that way: it confounded QA-708's first run by presenting as "permissions preserved" when the write had simply been skipped, which is exactly how it would mislead someone in production.
## Confidence
- **Mechanism: high.** Read from source; the missing refresh and the defaulted `update_config_obj` are both direct.
- **Blast radius: moderate.** Found in passing rather than by a systematic sweep across config keys. Which keys can be reached this way, and whether any of them are load-bearing enough to cause a second-order failure, has not been established.
## Related
- #2067 — nested `HARPER_SET_CONFIG` removal leaves an empty object that permanently fails validation
- #1953 — docs and code disagree on `HARPER_SET_CONFIG` removal semantics
- #2095 — tracker for the false-green class this belongs to: the surface reports success for work that didn't happen
---
_Originally filed as a raw dispatch finding (task `qa-wave-2026072414`); rewritten during backlog triage. No new investigation beyond the source read described above._
Contributor guide
Assessment
This issue has not been assessed yet.