Skip to content

fix(hybrid): resolve system timezone through /usr/share/zoneinfo.default - #6

Open
brettporter wants to merge 1 commit into
HelloThisIsFlo:mainfrom
brettporter:fix/zoneinfo-default-macos-resolution
Open

brettporter wants to merge 1 commit into
HelloThisIsFlo:mainfrom
brettporter:fix/zoneinfo-default-macos-resolution

Conversation

@brettporter

Copy link
Copy Markdown

Summary

  • On a clean macOS install, /etc/localtime can resolve through /usr/share/zoneinfo.default instead of /usr/share/zoneinfo — likely macOS 27 (Tahoe successor) rather than an installation problem, since both /usr/share/zoneinfo and /var/db/timezone/zoneinfo are themselves symlinks that ultimately land on .default on affected systems.
  • _get_local_tz() (src/omnifocus_operator/repository/hybrid/hybrid.py) derived the IANA timezone name by splitting the resolved path on the literal substring "zoneinfo/". Against the .default variant this substring never matches, so the split is a no-op and the entire absolute path gets passed to ZoneInfo(...), which raises ValueError: ZoneInfo keys may not be absolute paths, got: /usr/share/zoneinfo.default/Australia/Sydney.
  • Because this runs at module import time (_LOCAL_TZ = _get_local_tz()), the failure isn't contained to timezone handling — it crashes the import of HybridRepository entirely, breaking server startup on affected machines.
  • Fix: use a regex that strips either zoneinfo/ or zoneinfo.default/ as the prefix, so the IANA name resolves correctly regardless of which directory the symlink chain lands on. Verified against all three real path variants (/usr/share/zoneinfo/..., /usr/share/zoneinfo.default/..., /var/db/timezone/zoneinfo/...).
  • Added regression coverage — _get_local_tz() previously had zero test coverage since existing tests monkeypatch _LOCAL_TZ directly rather than exercising the resolution logic itself.

Test plan

  • New parametrized test (TestGetLocalTz in tests/test_hybrid_repository.py) covers all three symlink resolution variants
  • uv run ruff check / uv run ruff format --check — pass
  • uv run mypy src/ — pass
  • Full uv run pytest --cov-fail-under=80 — pass (pre-existing, unrelated test_due_today_returns_tasks_due_today flake noted separately, not touched by this change)

🤖 Generated with Claude Code

_get_local_tz() derived the IANA timezone name by resolving /etc/localtime
and splitting on the literal substring "zoneinfo/". On a clean macOS
install, the symlink chain can resolve to /usr/share/zoneinfo.default
instead of /usr/share/zoneinfo, so the split silently no-ops and the
full absolute path gets passed to ZoneInfo(), which rejects it with
"ZoneInfo keys may not be absolute paths". Since this runs at import
time, it broke the server (and every test importing HybridRepository)
on affected machines.

Use a regex that strips either zoneinfo variant so the IANA name
resolves correctly regardless of which directory the symlink chain
lands on.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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