Skip to content

fix(routines): crontab lines short enough for cron to actually run - #827

Merged
bborn merged 2 commits into
mainfrom
task/5715-fix-ty-routines-schedule-writes-cron-lin
Oct 11, 2026
Merged

bborn merged 2 commits into
mainfrom
task/5715-fix-ty-routines-schedule-writes-cron-lin

Conversation

@bborn

@bborn bborn commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Root cause

renderCronLine inlined the invoking shell's entire $PATH into every crontab line, making them 2,000–2,400 chars, and macOS (Vixie) cron silently drops command lines over ~1,000 chars — so those routines never fired. Separately, the line redirected into <state dir>/cron.log without ensuring that directory exists, so a missing dir also failed the job before ty ever ran.

Fix

  • Wrapper script instead of inline PATH. InstallSchedule writes <state dir>/cron-run.sh (0755) that sets PATH (deduplicated) and execs ty run <name>. The crontab line is now <expr> /bin/sh '<wrapper>' >> '<log>' 2>&1 # ty:routine:<name> — ~150 chars regardless of PATH.
  • Hard guard: a generated line over 900 chars returns an error instead of being installed.
  • mkdir -p the routine state dir at schedule time (both backends; launchd logs there too).
  • launchd plist: PATH is deduplicated and XML-escaped (no length issue there, so the wrapper isn't used).
  • ty routines schedule --print now also prints the wrapper for the cron backend.
  • Cron-marker upsert/remove behavior is unchanged (existing tests pass untouched).

Tests

  • 5,000-char PATH → line stays under the limit, contains no PATH=, points at the wrapper; wrapper carries the PATH.
  • Overlong line (huge state dir) → error.
  • Install creates the state dir and an executable wrapper.
  • The wrapper actually runs under /bin/sh: sets PATH (deduped, with a ' in it) and execs ty with run scout.

go test ./internal/routine/ passes. In go test ./..., the only failure is internal/executor TestEnsureTaskWindow_ExportedEnvVarsReachLiveShellPane. It also fails on this host without this change (it depends on tmux) and is unrelated.

After merge: re-run ty routines schedule for ayla-scholarships, ayla-volunteering and ik-board-sweep. I did not touch the live crontab.

🤖 Generated with Claude Code

bborn and others added 2 commits October 8, 2026 07:33
The cron line inlined the invoking shell's entire $PATH, producing 2,000+
char lines that macOS (Vixie) cron silently drops. PATH now lives in a
per-routine wrapper script (<state dir>/cron-run.sh) that execs `ty run`,
and the crontab line just invokes it; lines over 900 chars are refused.

Also create the routine's state dir at schedule time — cron.log/launchd.log
redirect into it, and a missing dir failed the job before ty started.
PATH is deduplicated (and XML-escaped) in the launchd plist too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… raw PATH

CI's PATH has duplicate entries, which the plist now collapses.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@bborn
bborn merged commit dce2974 into main Oct 11, 2026
4 checks passed
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