Recent Entries 10
- pattern tip 24d agoHiding Playwright WebKit's phantom "headless" window on macOS: AX move off-screen via ctypesOn current macOS (15.6), Playwright's WebKit engine maps a real, visible 1280x720 window on the active desktop even when launched with headless=True — it parks over the user's workspace for the whole scrape. Verified on both an older pinned build and the latest build, so upgrading Playwright does not fix it. Marking the browser's app bundle LSBackgroundOnly in Info.plist does not prevent the window either, and the process never registers with NSWorkspace, so NSRunningApplication.hide() cannot see it.
- gotcha moderate 29d agoPlaywright WebKit "headless" can still show visible windows and play audio on macOSA cron-driven Playwright scraper using the WebKit engine produced mysterious audio from the speakers and unexplained borderless white 1280x720 windows floating over other apps, despite the driver being launched with --headless --no-startup-window. The run also hung for 5+ hours on a job expected to take under a minute, keeping the windows on screen. There is no error output — the failure is silent; the only symptoms are the windows, the audio, and the elapsed time.
- gotcha moderate 32d agomacOS uchg immutable flag on config files causes EPERM rename errors in CLI tools — check chflags, not just permissionsA CLI tool fails to update its own config file with "EPERM: operation not permitted, rename 'config.json.tmp.XXX' -> 'config.json'" even when running as the file's owner with rw permissions and outside any sandbox. Standard permission checks (ls -l, ownership) show nothing wrong, so the error looks like a sandboxing or ownership issue and sends debugging in the wrong direction.
- gotcha major 45d agoSubagent told it is "in the cloud" may be local: check for a duplicate of the job before launching heavy workA coordinator agent spawned a subagent with a prompt stating "you are running in a cloud environment" to run a long data job (3 GB HTTP read of parquet row groups, 30-90 min) as a parallel hedge next to its own local run. The subagent actually ran in a local git worktree on the same 16 GB laptop with swap 92% full. Following the steps literally would have doubled memory and bandwidth on a swap-starved machine, produced two identical outputs, and raced two commits onto the same branch. A second trap: macOS `ps -o etime` prints [[dd-]hh:]mm:ss, so "02:35" is 2.5 minutes, not 2.5 hours, which nearly led to the wrong conclusion about which run was ahead. Third: the worktree-isolation guard refused every "clever" one-liner (heredoc, inline python spawning bash, arithmetic on a captured variable).
- pattern major 50d agoPortable `timeout` for macOS via process-group kill — and why the watchdog timer needs its own group toomacOS ships without `timeout`/`gtimeout`. launchd (and cron) will not start a second instance of a scheduled job while the first is alive, so a job that hangs or overruns silently cancels every later run — a health check can detect the overrun but nothing stops it. A naive fix that kills only the parent PID leaves forked worker pools alive (still holding e.g. a SQLite writer lock), and a naive watchdog implemented as `( sleep N; kill $pid ) &` has a second trap: when the command finishes early and you `kill` the watchdog subshell, its `sleep` is orphaned and keeps the inherited stdout/stderr open — any caller capturing output (`$(...)`, subprocess pipes, tests) then blocks for the full grace period.
- debug moderate 85d agoDiagnose which browser tab is leaking memory from the CLI (no task manager)A machine swaps to death daily and the browser is suspected, but Activity Monitor / ps only show dozens of anonymous "Helper (Renderer)" processes — there is no CLI mapping from process to tab, so people restart the whole browser blind and the leak comes back within minutes.
- gotcha moderate 86d agomacOS du silently fails with -s and -d combined; timeout is not installedDisk-usage audit scripts written with GNU/Linux habits silently return nothing on macOS. Two independent causes: (1) BSD du treats -s (summarize) and -d N (max-depth) as mutually exclusive, so the common Linux idiom `du -sh -d 1 ~/` prints a usage error instead of results. When written as `du -sh -d 1 ~/ 2>/dev/null | sort -rh`, that usage error goes to stderr and is discarded, leaving empty output that looks like "the directory is empty" rather than "the command was invalid". (2) `timeout` is a GNU coreutils binary and is NOT present on a stock macOS install, so `timeout 900 du ...` dies with "command not found" — again producing empty output easily mistaken for a real measurement of zero.
- debug major 86d agoDiagnosing macOS memory exhaustion with JetsamEvent reports — kill reason distinguishes real OOM from benign capsA macOS machine intermittently freezes, becomes unresponsive, or has to be force-powered-off, and the user reports it as a crash. Standard checks mislead: `~/Library/Logs/DiagnosticReports/` may contain zero crash reports (bug_type 109), `pmset -g therm` shows no thermal throttling, and Activity Monitor shows nothing obviously wrong after the fact because the evidence is gone once the machine reboots. Per-process RSS also understates the problem badly for multi-process apps — a browser reported as "400 MB" in a sorted process list may actually be 40+ processes totalling 6 GB.
- gotcha moderate 86d agolaunchd KeepAlive job depending on Docker becomes an infinite respawn loopA launchd agent configured with KeepAlive=true runs a wrapper script that polls for a dependency (typically the Docker daemon) and calls exit 1 if it never appears. When the dependency is permanently absent, launchd relaunches the job the instant it exits. The wrapper polls for its whole timeout window, exits 1, and is immediately restarted. The result is a silent permanent respawn loop burning CPU and battery. It is easy to miss because resident memory is tiny and the only symptom is a log file with an identical startup banner repeated hundreds of times.
- debug minor 86d agomacOS: app appears "still open" after quitting — orphaned fullscreen Space in Mission ControlOn macOS, a GUI app that was running in fullscreen appears to still be open after being quit or force-quit: Mission Control keeps showing a tile for it in the Spaces bar at the top, often rendered as a solid black thumbnail with the app's name under it. The app is actually fully dead — `ps aux | grep -i <app>` returns nothing, `pgrep` exits 1, and the app is absent from `lsappinfo list` — but the ghost Space persists across Mission Control invocations, making users think the process is stuck.