How a Silent Parser Bug Deleted 31 Blog Posts Without Warning
Discovery: "Wait, Why Are There So Few Posts?"
Last week during a routine content update, I opened our live blog page and something felt off: only 12 posts were showing. I distinctly remembered having over 40 posts just a few days earlier.
My first thought was browser cache or pagination issues. But after refreshing the page and trying different browsers, same result: 12 posts. When I checked the backup posts.js file in my local dev environment, there were 43 posts.
31 posts had vanished. And the worst part: we hadn't received a single error message.
Diagnosis: The Silent Error-Swallowing Parser
I started digging through our automated publishing system to find the culprit. Here's how our system worked:
- When a new blog post is created, the script reads the existing
posts.jsfile - Parses the content as JSON
- Adds the new post to the list
- Writes the updated list back to the file
The problem was in the parser code at step two:
// WRONG CODE - Never do this!
function loadPosts() {
try {
const content = fs.readFileSync('posts.js', 'utf8');
const posts = JSON.parse(content);
return posts;
} catch (error) {
console.log('Parse error, returning empty list');
return []; // ๐จ Silently returns empty array!
}
}
The day before, during a manual edit, we'd accidentally introduced an invalid character into posts.js (probably a missing comma or quote). The file was no longer valid JSON.
When the script ran, JSON.parse() threw an error, but the catch block swallowed it and silently returned an empty array. The system thought "no existing posts, just save the new one" and overwrote the file.
31 posts gone in an instant. No warning, no logs, nothing.
Recovery Operation
1. Restoring from Backup
We got lucky: my local dev environment had a backup from the day before. But this meant losing 2 new posts that had been added in the last 24 hours.
I checked the Git history:
git log --all --full-history -- posts.js
git show abc123:posts.js > posts_recovered.js
Fortunately, one of the 2 missing posts was still on the live site (cached). I found the other in our drafts folder. After manually merging everything, we recovered all 43 posts.
2. The New Never-Fail-Silently Parser
To prevent this from ever happening again, I rewrote the parser from scratch:
// CORRECT CODE
function loadPosts() {
const backupPath = `posts_backup_${Date.now()}.js`;
try {
const content = fs.readFileSync('posts.js', 'utf8');
// Create backup first
fs.copyFileSync('posts.js', backupPath);
const posts = JSON.parse(content);
// Basic validation
if (!Array.isArray(posts)) {
throw new Error('posts.js is not an array!');
}
if (posts.length === 0) {
throw new Error('posts.js is empty - this is probably a bug!');
}
return posts;
} catch (error) {
console.error('โ CRITICAL ERROR: Cannot read posts.js!');
console.error('Error details:', error.message);
console.error('Backup file:', backupPath);
// STOP the process - prevent data loss
process.exit(1);
}
}
Key features of the new approach:
- Automatic backups: Timestamped backup before every read
- Validation: Even an empty list is considered suspicious
- Clear error messages: Exactly what went wrong is logged
- Process termination: System stops instead of continuing with bad data
The Bigger Lesson: "Fail Fast" Principle
This incident reminded us of a critical software development principle: silent error swallowing is far more dangerous than loud failures.
For content management systems in particular, watch out for:
- Never return default values: If a file can't be read, throw an error instead of returning an empty list
- Logging unexpected conditions isn't enough: Stop the process on critical errors
- Automatic backups are mandatory: Especially before overwrite operations
- Add validation layers: "File was read" isn't enoughโask "does the content make sense?"
Check Your Own Site
To avoid a similar issue, audit your codebase for:
- Review
catchblocks in your content management scripts - Search for code that returns default values (
return [],return {}) - Review backup strategies for critical files
- Regularly monitor logs from automated processes
AICompatible.com's site crawler automatically detects these kinds of structural issues. Specifically, our content consistency checks can help you catch unexpected content loss early. But your most important line of defense is making sure your code screams loudly instead of failing silently.
Bottom line: we recovered the 31 posts, hardened the system, and learned a valuable lesson. Sometimes the best teacher is the data you almost lost.