- Knowledge
- technology
- OOP
- Tips
- Programming
- Tips
- Tutorial
- SEO
- Ranking
- Knowledge
- Special Day
- Seo
- Bug
- Data science
- Seo
- artificial intelligence
- Machine Learning
- Robotics
- happyNewYear2021
- newYearEve
- 2021
- Automation
- Smart Home
- Career
- Best Practices
- Git
- Logging
- Web Fundamentals
- DNS
- HTTPS
- Performance
- AI Tools
- ChatGPT
- Claude
- Gemini
- Laravel
- Eloquent
- MySQL
- HTTPS
- TLS
- Web Security
- Certificates
- Developer Life
- Debugging
- Docker
- DevOps
- Transactions
- Queues
- LLMs
- AI
- AI Coding
- Developer Tools
- React Native
- Expo
- Kate PMS
- Mobile Apps
- Laravel
- Authentication
- Sanctum
- Cookies
- API Design
- Payments
- Idempotency
- DeepSeek
- Open Source AI
- LLMs
- AI News
- Git
- Version Control
- AI Coding
- Prompting
- PHP
- Checklist
- MCP
- AI Agents
- OpenAI
- Architecture
- Microservices
- Modular Monolith
- Estimation
- Developer Life
- Project Planning
- Humour
- OAuth
- OpenID Connect
- Authentication
- Embeddings
- Vector Search
- RAG
- pgvector
- OpenAI
- GPT-4.1
- Codex CLI
- Events
- Testing
- Clean Code
- Maintainability
- Code Review
- Webhooks
- API
- Security
- Claude Code
- Workflow
- AI
- LLM
- Prompt Injection
- Mobile
- React
- Networking
- TCP
- UDP
- HTTP/3
- CLAUDE.md
- AWS
- Cloud Security
- Backups
- PHPUnit
- Software Engineering
- Leadership
- Communication
- RAG
- Embeddings
- AI Engineering
- IT Infrastructure
- Networking
- Access Control
- CI/CD
- GitHub Actions
- Gemini CLI
- Claude Code
- JavaScript
- Async/Await
- Node.js
- Promises
- Security
- Cryptography
- Passwords
- MySQL
- Database
- Vibe Coding
- Software Quality
- DNS
- Code Reading
- Onboarding
- Productivity
- Background Jobs
- Developer Humour
- Estimates
- Dev Life
- JWT
- o3-mini
- DeepSeek R1
- Rate Limiting
- Kate PMS
- E-Signing
- Audit Trail
- REST
- GraphQL
- API Design
- Laravel 12
- Upgrade Guide
- Open Source
- Self-Hosting
- Task Scheduling
- Cron
- Secrets
- CORS
- PHP
- PHP-FPM
- OPcache
- GitHub Copilot
- Software Architecture
- Engineering
- TypeScript
- JavaScript
- Type Safety
- AI Security
- React Native
- Product Design
- AI Agents
- Kiro
- Queues
- Redis
- RabbitMQ
- AWS SQS
- Nginx
- Apache
- GPT-5
- gpt-oss
- Clean Code
- Architecture
- Naming
- Documentation
- Career
- ADR
- Teamwork
- Supply Chain
- Kate HRM
- HR Software
- Permissions
- System Design
- Pagination
- SSH
- Linux
- Big O
- Databases
- Laravel Boost
- MCP
- Developer Skills
- Validation
- Databases
- Indexes
- Code Quality
- Deployment
- Developer Humour
- Feature Flags
- Code Review
- Pull Requests
- Docker
- Cursor
- Authorization
- RBAC
- Gemini
- Long Context
- PHP 8.4
- Caching
- Dependency Injection
- Web Performance
- Browser
- CSS
- Database
- Migrations
- ChatGPT
- AI for Developers
- Monitoring
- On-Call
- REST
- Backend
- SQL
- NoSQL
- Database Design
- Coding Agents
- Claude 4
- API Resources
- REST API
- Load Balancing
- Scaling
- AWS
- AI Tools
- Claude
- Sora 2
- CTE
- 2FA
- TOTP
- Programming Languages
- Prompts
- Developer Workflow
- API Gateway
- APIs
- Passport
- API Auth
- Learning
- Burnout
- Developer Growth
- Web Development
- SEO
- Kate Mall
- ChatGPT Atlas
- Agent Skills
- Middleware
- Laravel 12
- Collections
- Context Window
- Monitoring
- Commit Messages
- Self Review
- Growth
- Regex
- Programming Basics
- Text Processing
- Database Design
- Normalization
- Linux
- Server Security
- Linux Foundation
- Open Standards
- Legacy Code
- Documentation
- AI Workflow
- File Uploads
- Test Data
- Hashing
- Performance
- Caching
- Enums
- Scope Creep
- Estimation
- Codex
- Gemini CLI
- Timezones
- Carbon
- Bugs
- PHP 8.5
- Gemini 3
- GPT-5.1
- Data Integrity
- Event Loop
- Async
- Opus 4.5
- AI Models
- React
- Forms
- Frontend
- Backups
- AI Images
- DALL-E
- Midjourney
- Race Conditions
- Concurrency
- Legacy Code
- Refactoring
- Senior Engineer
- Scope
- LLM
- CDN
- Web
- Sub-Agents
- Soft Deletes
- Audit Log
- Concurrency
- AI Learning
- NestJS
- AI Evals
- Policies
- SPF DKIM DMARC
- Unicode
- UTF-8
- Knowledge Graph
- Value Objects
- Technical Debt
- Feature Flags
- Laravel Pennant
- Deployment
- Copilot
- Composer
- Dependencies
- Artisan
- Automation
- AWS S3
- Object Storage
- Cloud
- Small Language Models
- Ollama
- Production
- Sessions
- HTTP
- Mentoring
- SQL
- Virtual Machines
- Web Development
- HTTP/2
- QUIC
- Web Performance
- AI Integration
- LLM API
- SOLID
- OOP
- Hosting
- Serverless
- Merge Conflicts
- Temperature
- AI Development
- Reverse Proxy
- Nginx
- Infrastructure
- Verification
- Passkeys
- WebAuthn
- Teams
- Communication
- Stakeholders
- Monorepo
- CI/CD
- Versioning
- JSON Schema
- Livewire
- Inertia
- Meetings
- Distributed Systems
- Privacy
- Full-Stack
- T-Shaped Skills
- Money
- Notifications
- Web Security
- HTTP Headers
- CSP
- Function Calling
- Load Testing
- k6
- Data Extraction
- Debugging
- WebSockets
- SSE
- Real-Time
- Laravel Reverb
- Infrastructure as Code
- Terraform
- Side Projects
- Laravel Pint
- OpenAPI
- Swagger
- UX
- Multimodal
- Jest
- Pair Programming
- APIs
- Rate Limiting
- Resilience
- Dev Humour
- Design Tokens
- JWT
- API Keys
- Sessions
- PHPStan
- Rector
- Incidents
- Reporting
- Dashboards
- Zero Trust
- IAM
- Search
- Laravel Scout
- Junior Developers
- Mentoring
- Images
- WebP
- AVIF
- Bug Reports
- Let's Encrypt
- Design Docs
- Software Design
- Observers
- Replication
- Accountability
- Data Structures
- Reliability
- LLM Memory
- Error Handling
- Payments
- Payment Gateway
- Webhooks
- PCI DSS
- Observability
- OpenTelemetry
- Personal Brand
- Writing
- Conventions
- Dates
- Scheduling
- Disaster Recovery
- Compression
- Brotli
- Deadlines
- Developer Habits
- State Machines
- Tech Roles
- UUID
- ULID
- Horizon
- Planning
- Engineering Culture
- Ownership
- Soft Skills
- Socialite
- Cost Control
- Collations
- Unicode
- Octane
- PostgreSQL
Me vs the Bug That Only Happens in Production
About Post
Tests: green. Staging: green. My laptop: flawless, a picture of health.
Production: "Hi, a few users are saying the invoice page is blank?"
A few users. Not all of them. Not me. Not anyone I can phone. Welcome to the most humbling genre of software bug, the one that only exists where real people are using real data on a real server. Every developer meets it eventually, and we all go through the same stages.
The five stages of a production-only bug
Stage 1: Denial
❌ "Works for me." You open the page. It works. You open it in incognito. It works. You ask the user to clear their cache, with the quiet confidence of someone who has solved nothing.
Stage 2: Archaeology
❌ You open the logs. There are thousands of lines. Most of them say Something went wrong, with no user, no request and no clue. One says Undefined array key "address", which is both the answer and completely useless, because it doesn't say whose address.
Stage 3: Bargaining
❌ "What if I just add a dd() on production for one minute?" You know this is wrong. You think about it anyway. You compromise with a Log::info('HERE 1'), and then 'HERE 2', and deploy twice.
Stage 4: The discovery
❌ It turns out the bug only happens for customers created before a migration last year, whose address field is null instead of an empty string. Your local database has fifty tidy factory users, all with perfect addresses. Production has years of history, imports and edge cases. Of course it worked on your machine. Your machine has never met a real customer.
Stage 5: Acceptance
❌ The fix is one line. Finding it took the whole afternoon. You whisper "never again", knowing full well there will be an again.
Why production is different
Production-only bugs are rarely mysterious once you find them. They almost always come from one of three gaps:
- Data: old records, nulls, huge values, odd characters, users with permissions nobody planned for.
- Config: different environment variables, cache drivers, queue drivers, timezones, PHP extensions.
- Scale and timing: concurrency, real traffic, slow third-party APIs, jobs overlapping.
You can't remove these gaps completely. But you can make them visible, and that's what turns an afternoon into ten minutes.
What actually helps
✅ Logs with context, not just messages. A log line is only useful if it tells you who, what and where. In Laravel, add context once and every log line in that request carries it:
// In a middleware, early in the request
Log::withContext([
'request_id' => (string) Str::uuid(),
'user_id' => $request->user()?->id,
'route' => $request->route()?->getName(),
]);
Now "Undefined array key" comes with a user ID you can look up, and a request ID you can follow across every line it wrote. An error tracker that groups exceptions and shows the request details turns the archaeology stage into a quick search.
✅ Config parity. Run the same PHP version, extensions, database engine, cache and queue drivers locally as in production. Docker makes this much easier. If production uses Redis and your laptop uses the array cache driver, you're testing a different app.
✅ Feature flags for risky changes. Release new code paths to a small group first, staff accounts or a handful of users, and widen it once it behaves. If something breaks, you turn the flag off instead of rolling back a deploy. Laravel Pennant gives you this out of the box:
if (Feature::active('new-invoice-page')) {
return view('invoices.v2', compact('invoice'));
}
return view('invoices.show', compact('invoice'));
✅ Reproduce with real-like data. Factories should create messy users too: nulls, very long names, Arabic and accented characters, old statuses, missing relationships. For tricky bugs, an anonymised copy of production data in a safe environment beats any amount of guessing. Just make sure personal information is scrubbed before it leaves production.
The rule: when you can't reproduce a bug, don't guess harder. Add the visibility that would have told you the answer, then wait for it to happen again. The second time, it can't hide.
The real lesson
"It only happens in production" isn't bad luck. It's production telling you exactly where your test data and environment are lying to you. Each one of these bugs is a free lesson about the gap, if you fix the gap and not just the line.
So yes, add the null check. Then add the messy user to your factories, the context to your logs, and the flag to your next risky feature.
What's the strangest production-only bug you've chased? Bonus points if the cause was a single character.

Be first to comment it...