Skip to content

config unset accepts any key, and reports success when nothing was written #40

Description

@PeGa

What happens

focus config set validates its key against _valid_key. focus config unset does not, and the key is interpolated unescaped into a sed address:

env_key="REFOCUS_${key}"
[[ -f "$ENV_FILE" ]] && _rewrite_env "/^${env_key}=/d"

Any / in the key ends the address early and the rest becomes sed program text:

$ focus config set NUDGE_INTERVAL 9
✅ NUDGE_INTERVAL=9

$ focus config unset 'x/d;s/^.*$//'
sed: -e expression #1, char 23: unknown option to `s'
✅ Unset x/d;s/^.*$// (reverts to default)

$ echo $?
0

sed refused the malformed program, so .env survived — but the command still printed and exited 0.

Why the success message is wrong

_rewrite_env (lib/config.sh:39) ends with rm:

sed "$expr" "$ENV_FILE" > "$tmp" && cat "$tmp" > "$ENV_FILE"
rm -f "$tmp"

The function returns rm's status, not the rewrite's, so a failed rewrite looks like success to the caller.

The two halves fail differently, which is why this hid for so long:

  • cat "$tmp" > "$ENV_FILE" is the final command of the && list, so set -e catches it. Making .env read-only correctly gives rc=1 and no .
  • sed ... > "$tmp" is non-final, so set -e skips it, && short-circuits, rm returns 0, and the caller prints .

Why it's needed

.env is not corrupted, so the blast radius is small. The problem is that the tool reports success for work it did not do — and a that can be a lie devalues every other the tool prints.

Suggested fix

  • Gate unset on _valid_key, the same as set.
  • Make _rewrite_env return the rewrite's status rather than rm's, so a failed write reaches the caller.

Location

lib/config.sh_rewrite_env at :32-41, the unset branch at :94-99.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions