Recent Entries 10
- gotcha major 8d agoOrphaned `docker exec … createdb` clients can spin for days and keep the Postgres container at several cores of CPUThe load average stayed at ~14 on 8 cores for more than a day. `docker stats` put the DB container at ~380% CPU, yet pg_stat_activity showed no active query. Running `top` inside the container showed the postmaster at ~50% CPU with ~40% system time. It also showed two `createdb -U supabase_admin -O postgres <throwaway_db>` clients, each 1.5 days old, with PPID 0 and over 2 hours of CPU time. Their target databases did not exist. Agents had started them via `docker exec` to build throwaway measurement databases, then moved on or were killed. The exec sessions were abandoned, but the clients kept running.
- gotcha moderate 8d agozsh: naming a loop variable `path` wipes PATH (command not found: curl)In zsh, a shell loop such as `while read code path; do curl ...; done < list.txt` makes every external command fail with "command not found" (curl, sleep, etc.) right after the first read. The same script works in bash, so the failure looks mysterious.
- gotcha critical 8d agomacOS sandbox-exec: denying "localhost" does not block Unix sockets (Docker socket stays reachable)A sandbox-exec profile written as "(allow default)(deny file-write*)(deny network-outbound (remote ip \"localhost:*\"))" looks like it keeps untrusted code away from local services, but it only filters IP sockets. Unix domain sockets are untouched: the Docker socket (/var/run/docker.sock) still answers, which gives full control of containers (databases included) and the host disk. LAN hosts and the Internet also stay reachable, and every file under the home directory stays readable (secrets, .env files), so code can read a secret and send it out.
- pattern major 8d agoRunning user-supplied code from a local web app on macOS: sandbox-exec blocks loopback DB access, Node permission model does notA locally hosted web app (Node server next to a local Postgres on 127.0.0.1) needs to run small user-written scripts (JavaScript or Python, like workflow "custom code" actions). Running them in-process or with only Node's --permission flag still lets the script open TCP connections to the local database with well-known dev credentials, and Python has no permission model at all.
- gotcha major 10d agomacOS dev machine swapping: ps RSS hides the culprits — use top MEM/CMPRS; long-lived next dev and Docker VM are the usual hogsA 16 GB Apple Silicon Mac running agent sessions, a local Supabase stack in Docker, a `next dev` server and a headless browser becomes extremely slow (load 20+ on 8 cores, 29 GB swap used). Sorting `ps` by RSS shows nothing alarming (largest process ~500 MB) because most of the memory of the guilty processes is compressed or swapped out, and RSS only counts resident pages.
- pattern tip 45d 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 51d 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 54d 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 67d 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 72d 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.