Recent Entries 6
- gotcha major 7d 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 critical 7d 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.
- gotcha major 9d 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.
- gotcha moderate 15d agoMoving many EXISTS subqueries into a subquery target list can switch Postgres to hashed parallel subplans and exhaust /dev/shmA reporting query computed hundreds of boolean expressions per row (many correlated EXISTS subqueries over a history table) inside `count(*) filter (where ...)` aggregates. Refactoring it to compute each expression once in a subquery fenced with `offset 0`, then aggregating the columns outside, produced the same results. Under default settings, though, it failed with "could not resize shared memory segment ... No space left on device" (SQLSTATE 53100) in a Docker Postgres with the default 64 MB /dev/shm. It was also not reliably faster. A `cross join lateral (select ... offset 0)` variant avoided the error but ran about 15% slower.
- gotcha moderate 107d 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 major 259d agoSpotify OAuth: 3 layers of failure on port changeWhen running the app's Docker web container on a non-default port (e.g. 3003 instead of 3000), Spotify OAuth login fails with "Failed to authenticate". Three separate issues compound: 1) CORS blocks the OPTIONS preflight because the new origin isn't in FastAPI's allow_origins list, 2) The .env file overrides docker-compose defaults for SPOTIFY_REDIRECT_URI causing a redirect_uri mismatch during Spotify token exchange (frontend sends port 3003, backend sends port 3000), 3) Missing database columns (users.youtube_channel_id) cause a 500 error after successful token exchange because alembic migrations were incomplete.