Skip to content

fix(macos): resolve duplicate .env keys last-wins in read_env_value - #6177

Closed
0xacee wants to merge 1 commit into
Osmantic:public-betafrom
0xacee:fix/macos-env-dup-precedence
Closed

0xacee wants to merge 1 commit into
Osmantic:public-betafrom
0xacee:fix/macos-env-dup-precedence

Conversation

@0xacee

@0xacee 0xacee commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Both macOS copies of read_env_value (installers/macos/lib/env-generator.sh and installers/macos/ods-macos.sh) return the first matching line of a duplicated .env key, while the Linux CLI reader (_env_get_raw in ods-cli) and every dotenv consumer (docker compose, python-dotenv, the compose stack itself) resolve duplicates last-wins. Same file, different semantics per platform.

Why this matters

The backfill guards — [[ -z "$(read_env_value ... SHIELD_API_KEY)" ]], the Hermes session token check, ODS_SESSION_SECRET, WEBUI_AUTH, GPU limit/reservation reads — all key off this function. A .env containing SHIELD_API_KEY= followed by SHIELD_API_KEY=real-key (a common hand-edit artifact: appended key above a previously generated one, or a preserved line above an appended one) reads as empty on macOS, so the installer/CLI regenerates the key and upsert_env_value rewrites all duplicate lines — silently destroying the operator's real key. On Linux the same file is correctly read as real-key and preserved. Aligning to last-wins matches _env_get_raw (tail-equivalent awk loop) and actual dotenv semantics, and makes the "is this key set?" check consistent with what consumers will resolve at runtime.

Changes

  • ods/installers/macos/lib/env-generator.sh — sed -n '1p' → tail -n 1 in read_env_value
  • ods/installers/macos/ods-macos.sh — same fix in its read_env_value copy
  • ods/tests/test_macos_read_env_value_precedence.py — new regression test exercising both copies: last-duplicate resolution, empty-first/valued-last ordering, missing-key empty read, single-key read, and an end-to-end check that the backfill guard does not fire on a duplicated live key

Overlap check

Searched open/closed PRs for read_env_value, duplicate env handling, and the touched files:

Validation

  • python3 -m pytest tests/test_macos_read_env_value_precedence.py on this branch: 4 passed.
  • Same test against clean upstream/public-beta (4d725ee95): 4 failed — base returns the empty first line (expected last duplicate, got: ) and the guard fires on a live key (guard fired on a live key), reproducing the clobber path end to end.
  • Adjacent suites green: test_macos_upsert_env_value.py (1 passed), test-macos-direct-bind-bridge.sh, test-macos-installer-transitions.sh all pass; test-macos-native-model-store.sh skips (requires macOS).
  • tests/test-hermes-dashboard-session-token.py fails identically on clean upstream/public-beta — pre-existing stale anchor addressed separately in test(hermes): fix stale Linux anchors in session-token contract test #6173, not a regression from this change.
  • shellcheck -S error clean on both scripts; bash -n clean; git diff --check clean.

Pending: CI and maintainer review.

@0xacee 0xacee closed this Oct 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant