Articles
Industry news, technical articles, and product introductions
📚 Claude Tutorials Hub
40+ step-by-step Claude guides — prompt engineering, Claude Code, API, agents. Browse by topic →
Loading...
Industry news, technical articles, and product introductions
📚 Claude Tutorials Hub
40+ step-by-step Claude guides — prompt engineering, Claude Code, API, agents. Browse by topic →
Loading...
A production pipeline went dark two mornings in a row: logs stopped at 07:04, and every poll after that said 'record exists for today, skipping.' The root cause was PM2's cron_restart on a wake-every-5-minutes dispatcher — it kills the running instance (and its children) before starting a new one. Includes an 8-minute local reproduction: the cron_restart group started 9 times and finished 0; the resident-loop control finished 4 out of 4.
I exported ANTHROPIC_BASE_URL in .zshrc to point at a self-hosted API gateway, and Claude Code kept talking to Google Vertex anyway. On the same machine, a launchd-managed web UI insisted it wasn't authenticated at all. Neither bug was in the gateway — both were in the gap between 'I set the env var' and 'the process actually has it.'
A mascot scene card driven by SwiftUI's TimelineView had two defects: the snail mirror-flipped in place the first time you started a sound, and the background hard-cut when you stopped it. The first one took two rounds to bottom out — round one blamed a paused timeline desyncing the two clocks, and the flip survived the fix. The actual cause was one line of phase normalization, `raw < 0 ? raw + 1 : raw`, which took the few-dozen-millisecond fact that timeline.date trails Date() by a frame and wrapped it into a phase of 0.9999 — and facing direction happens to be a discontinuous function of phase at zero. This postmortem covers why .transition doesn't work inside TimelineView, how to express animation state as a pure function of time, and why a crossfade should be fade-in only, with no fade-out.
Building explainer videos with TTS + auto subtitles: the first 30 seconds were perfectly synced, then the subtitles drifted further and further behind, and the tail of the .srt degraded to 00:00:00 timestamps. The first instinct — patch the alignment (normalize numbers, loosen similarity thresholds) — treats symptoms. This postmortem shows the real cause: any 'whole-clip TTS + whisper transcription + post-hoc matching' pipeline drifts by construction, because it hands timing — which the generation step could produce directly — to a lossy reconstruction chain. The fix: sentence-level TTS with sample-accurate concatenation, where each subtitle's timestamp is the running sum of real wav sample counts. Sentence boundaries reset the error, so drift is physically impossible. Includes splitting rules, caching design, and the limits of the approach.
Claude Fable 5 officially ships with a 1M-token context window, yet the Claude Code status line kept showing 200k as the denominator. The first instinct — 'let's switch to a better statusline' — was wrong. This postmortem walks through the full debugging process: one line of tee to capture the statusline's stdin, hard evidence that the official field misreports 200000 for new models, and a model-table fix. Plus a general lesson: swapping tools never fixes a broken data source.