惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Microsoft Azure Blog
Microsoft Azure Blog
The Register - Security
The Register - Security
S
Securelist
Simon Willison's Weblog
Simon Willison's Weblog
T
The Exploit Database - CXSecurity.com
V
Vulnerabilities – Threatpost
NISL@THU
NISL@THU
P
Privacy & Cybersecurity Law Blog
V2EX - 技术
V2EX - 技术
O
OpenAI News
N
News and Events Feed by Topic
AI
AI
P
Proofpoint News Feed
Schneier on Security
Schneier on Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Cloudbric
Cloudbric
Help Net Security
Help Net Security
C
Cyber Attacks, Cyber Crime and Cyber Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Security Latest
Security Latest
Application and Cybersecurity Blog
Application and Cybersecurity Blog
L
LINUX DO - 热门话题
Cyberwarzone
Cyberwarzone
Scott Helme
Scott Helme
The Hacker News
The Hacker News
Hacker News - Newest:
Hacker News - Newest: "LLM"
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Google DeepMind News
Google DeepMind News
H
Hacker News: Front Page
C
Cisco Blogs
Webroot Blog
Webroot Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Hacker News: Ask HN
Hacker News: Ask HN
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
The Last Watchdog
The Last Watchdog
PCI Perspectives
PCI Perspectives
AWS News Blog
AWS News Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Know Your Adversary
Know Your Adversary
Latest news
Latest news
Forbes - Security
Forbes - Security
I
Intezer
Project Zero
Project Zero
C
CERT Recently Published Vulnerability Notes
T
Tenable Blog
TaoSecurity Blog
TaoSecurity Blog
S
Security @ Cisco Blogs
N
News | PayPal Newsroom
H
Heimdal Security Blog
W
WeLiveSecurity

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Friday Fixes: The Fix That Wasn't
Rob · 2026-06-26 · via DEV Community

Three bugs this month. All three looked fixed before they broke. The
date was quoted in 51 out of 52 posts. The model was pinned to a
specific version. The upload feature had been working in production for
weeks. Each one passed the obvious checks and failed somewhere else.

That's the theme for this Friday Fixes: the fix that wasn't. Not
bugs that went unnoticed, but bugs where a defense existed and the
failure found its way around it.

1. The Unquoted Date, Part Two

If this one sounds familiar, it should. I wrote an entire Friday Fixes
post
about
this exact bug class five weeks ago. An unquoted YAML date. gray-matter
parsing it as a Date object instead of a string. A crash downstream.

Last time it took down /admin/drafts. The fix hardened formatDate()
to coerce Date objects before calling .includes(). I verified it.
I shipped it. I wrote 2,000 words about it. I moved on.

This time it took down the homepage.

The symptom: vibescoder.dev loaded for a split second, then
flashed to Chrome's "This page couldn't load" screen. Every browser,
every profile, every device. The site was completely dead to visitors.

The twist: curl returned HTTP 200 with ~900KB of fully rendered
HTML. The server was fine. The crash was happening during React
hydration in the browser, invisible to any server-side test.

The cause: A new post had date: 2026-06-19 in its frontmatter.
No quotes. gray-matter parsed it as a Date object. In posts.ts,
the code does const meta = data as PostMeta and then spreads ...meta
into the return value. The as PostMeta cast told TypeScript the date
was a string. At runtime, it was a Date.

That Date object flowed through the server component, through the
RSC serialization boundary, and into PostListWithFilters, a "use
client"
component. React couldn't hydrate it. No global-error.tsx
existed to catch the crash. Dead page.

Why the May fix didn't prevent this: Because the May fix was in the
wrong layer. It hardened formatDate(), the function that happened to
crash that time. It never hardened posts.ts, the layer where the
Date object enters the system. The Date object simply found a
different path out.

The false start: The first fix attempt added meta.date instanceof
Date
to coerce the value. TypeScript rejected it:

Type error: The left-hand side of an 'instanceof' expression must be
of type 'any', an object type or a type parameter.

The same as PostMeta cast that hid the runtime bug also blocked the
fix. TypeScript believed meta.date was a string, so it wouldn't
let me check if it was a Date. The fix was to check data.date (the
raw gray-matter output, typed as any) instead of meta.date (typed
as string):

function normalizeDate(raw: unknown): string {
  if (raw instanceof Date) return raw.toISOString().split("T")[0];
  return String(raw);
}

Applied in all four functions that return post data. Also added a
global-error.tsx so future hydration crashes show a reload button
instead of a dead page.

What it cost: ~25 minutes of downtime on the public site. Three
commits across two repos, including the TypeScript false start. One
embarrassing realization that I'd written a blog post about the bug
and it happened again anyway.

2. The Model That Quietly Expired

The blog has a voice dictation flow: record a transcript, click
"Generate Post," get a draft. On June 18, clicking Generate returned
a red "Generation failed" banner. No useful error detail.

The cause: The generation pipeline called the Anthropic API with
model: "claude-sonnet-4-20250514". That model hit end-of-life on
June 15. The API started rejecting requests three days before anyone
noticed.

The clue was in the SDK itself:

// @anthropic-ai/sdk DEPRECATED_MODELS
'claude-sonnet-4-20250514': 'June 15th, 2026',

The fix: One line.

-model: "claude-sonnet-4-20250514",
+model: "claude-sonnet-4-6",

Merged as PR #17. Generation worked immediately after Vercel deployed.

Why it took three days: Two compounding failures:

First, there's no deprecation warning from the Anthropic API. The model
works on June 14. It doesn't work on June 15. No sunset header, no
grace period, no degraded response with a warning. Just errors.

Second, the catch block swallowed the error. The route handler logged
console.error("Generation error:", error) to the server, but returned
{ error: "Blog generation failed" } to the frontend. The actual
Anthropic error message, which almost certainly said something about
the model being retired, was buried in Vercel's server-side logs. The
user-facing error was a generic string that could mean anything.

A comment like // EOL: June 15, 2026 next to the model string would
have made this a 30-second fix. Surfacing the API error to the frontend
would have made it self-diagnosing. Neither existed.

3. Seven Commits for Three Lines

The Vacation Hub, a trip planning side project, has a photo gallery.
Upload photos from your phone, they land in Vercel Blob Storage. It
worked perfectly on the original deployment.

After a security hardening commit that added CSP headers, photo uploads
broke. Click upload, progress bar hits ~20%, hang forever.

The agent spent seven commits fixing this. The actual fix was three
lines.

What went wrong: The security commit added a Content-Security-Policy
header with connect-src 'self' https://*.public.blob.vercel-storage.com.
The Vercel Blob SDK's client-side upload() makes a PUT to
https://vercel.com/api/blob. That domain wasn't in connect-src.
The browser silently blocked the request.

But here's why seven commits: there were three independent bugs
stacked on top of each other, and fixing any one of them didn't resolve
the issue.

  1. CSP connect-src missing https://vercel.com caused the hang.
    The browser blocked the PUT, no error surfaced, the upload promise
    never resolved.

  2. Empty onUploadCompleted callback contributed to the hang. The
    SDK registered a webhook URL that Vercel would POST to after upload.
    The empty handler existed, so the SDK set it up, but the callback
    could silently fail.

  3. No multipart: true on the upload calls. Vercel Blob's single
    PUT has a 4.5MB limit. Modern phone photos regularly exceed that.
    Without multipart chunking, large files returned 413. But you'd
    never see the 413 if the request never got past CSP.

Each bug masked the next. Fix the CSP and uploads still hang (callback).
Remove the callback and large photos 413 (no multipart). The agent
tried each fix in isolation, concluded each one was wrong, and at one
point rewrote the entire upload flow to server-side FormData, which
introduced its own size limit problems.

The breakthrough came when I asked a simple question: "The original
deployment worked. What changed?"
A targeted git show on the
security commit would have found the CSP addition in minutes. Instead,
the agent read the current code looking for problems rather than
diffing backward from the last known working state.

The actual fix:

-connect-src 'self' https://*.public.blob.vercel-storage.com
+connect-src 'self' https://*.public.blob.vercel-storage.com https://vercel.com

Plus multipart: true on both upload() calls and removing the empty
callbacks. Three lines across two files.

What Connects Them

All three bugs involve a defense that felt complete but wasn't.

The date coercion in formatDate() protected the function that crashed
in May. It didn't protect the serialization boundary that crashed in
June. The model was pinned, but nobody tracked when the pin expired.
The security headers were added, but the SDK's upload domain wasn't in
the allowlist, and the error was swallowed so thoroughly that seven
commits went by before the agent found all three stacked failures.

Each fix addressed the symptom it could see. None of them addressed
the layer where the problem actually lived. The date needed to be
coerced at the parsing boundary, not at the formatting boundary. The
model needed a deprecation calendar, not just a version string. The
security commit needed a full audit of outbound domains, not just the
ones the developer remembered.

This is a pattern I keep seeing when building with agents. You're
working across dozens of sessions. The agent that added the CSP header
wasn't the agent that debugged the upload failure. The agent that
hardened formatDate wasn't the agent that needed to harden
posts.ts. Each session is competent in isolation. The gaps live in
the seams between sessions, where one agent's fix becomes another
agent's assumption.

The shared context between those sessions is you. The human
collaborator is the one who remembers that this date bug happened
before, that CSP headers can block SDK calls, that model strings have
expiration dates. Agents don't carry that across sessions unless you
build it into their context explicitly, with skills, with rules files,
with the kind of institutional memory that a solo developer usually
keeps in their head.

That means bugs accumulate. Not dramatically, not in ways that show up
in code review, but in the quiet gaps between what one session assumed
and what the next session inherited. An unquoted date here. A hardcoded
model string there. A CSP header that covers the domains you thought
about but not the one the SDK uses internally. Each one is fine until
it isn't.

The honest response to this is not to stop using agents. It's to be
vigilant. Scan for bugs and vulnerabilities constantly. Accept that
some will surface in production despite your best efforts. Build error
boundaries. Surface errors instead of swallowing them. Add the
global-error.tsx before you need it.

For a personal blog like this one, the risk is worth the reward. Agents
push to production, release velocity stays high, and when something
breaks, the blast radius is my own site. I can tolerate 25 minutes of
homepage downtime in exchange for shipping a post every other day with
a full admin toolchain that an agent built.

That calculus changes the moment customers or revenue depend on what
you're building. If this were a SaaS product, the unquoted date crash
would have been an incident, not a blog post. The three-day model
outage would have meant three days of broken functionality for paying
users. The seven-commit upload thrash would have been a sprint-derailing
debugging session with stakeholders asking for a postmortem.

The velocity is real. The bugs are real too. Know which game you're
playing.

By the Numbers

  • 1 unquoted date in 52 posts took down the public homepage
  • 1 deprecated model string broke generation for 3 days
  • 3 stacked bugs hid behind 1 security commit
  • 7 commits to find a 3-line fix
  • 3 fodder files consumed across 3 weeks of bugs
  • ~25 min homepage downtime (date crash)
  • 3 repos touched across all three fixes
  • 1 blog post about this exact bug class that didn't prevent the recurrence
  • 1 global-error.tsx added after the fact
  • 0 customers affected, because it's a personal site