✨ Darkwood IaExceptionBundle — When errors start explaining themselves
on February 8, 2026

Errors are not the problem. Silence is.
Every backend developer knows HTTP 500 errors. They happen. They are inevitable. And when they occur, the system usually does what it has done for decades:
Crash. Log. Move on.
But what if an error could do more than fail? What if it could explain itself?
That’s the origin of Darkwood IaExceptionBundle: a Symfony bundle that augments HTTP 500 errors with AI-generated explanation, probable causes, and suggested fixes, built on top of Symfony AI
🧭 The observation
Modern frameworks are excellent at:
- throwing precise exceptions
- producing stack traces
- exporting logs to observability platforms
Yet the responsibility of understanding an error is still delegated to humans.
The system knows:
- which exception was thrown
- where it happened
- under which conditions
But it remains silent. The developer must reconstruct meaning from fragments.
🧠 A simple idea
Instead of asking:
How do we fix errors automatically?
We asked something more modest:
What if the system could explain what just happened — in human terms?
Not to replace debugging tools. Not to repair anything. Just to formulate hypotheses faster.
⚙️ Why Symfony?
Symfony is uniquely positioned for this kind of experiment:
- a single, well-defined runtime
- an explicit
kernel.exceptionextension point - a culture of opt-in bundles
- and now, a first-class integration point via Symfony AI
This is not a “core framework feature” — and it shouldn’t be. It must stay opt-in, bounded, reversible.
🧩 What the bundle does (and does not do)
✅ What it does
On HTTP 500, the bundle can generate:
- a clear English explanation of the exception
- probable causes
- suggested fixes / next steps
- a confidence score
- an error ID for correlation
❌ What it does not do
- It does not fix bugs.
- It does not replace Sentry/logs.
- It does not claim certainty.
- It does not run unless enabled.
It’s an assistant, not an authority.
🔐 Safety first (non-negotiable)
Errors can contain sensitive details. That’s why the bundle is designed to be safe-by-default:
- It never sends headers, cookies, env vars, or request payloads to the model
- Stack traces are excluded by default (dev-only opt-in)
- If the AI fails or times out: Symfony’s default 500 handling runs as usual (fail-safe)
- The response status remains 500; only the body is augmented
📦 Install & use it in an existing Symfony project
Requirements
- PHP 8.2+
- Symfony 6.4+ also compatible with 7.x / 8.x
- A configured symfony/ai-bundle platform + agent
1) Install the bundle
composer require darkwood/ia-exception-bundle
2) Register the bundle (if needed)
If Symfony Flex doesn’t auto-register it, add it to config/bundles.php:
return [
// ...
Darkwood\IaExceptionBundle\DarkwoodIaExceptionBundle::class => ['all' => true],
];
3) Configure Symfony AI
Example OpenAI configuration:
# config/packages/ai.yaml
ai:
platform:
openai:
api_key: '%env(OPENAI_API_KEY)%'
agent:
default:
model: 'gpt-4o-mini'
4) Enable and configure the bundle
# config/packages/darkwood_ia_exception.yaml
darkwood_ia_exception:
enabled: true
only_status_codes: [500]
agent: 'ai.agent.default'
timeout_ms: 800
cache_ttl: 600
cache: 'cache.app'
include_trace: false
5) Enforce the timeout properly
To guarantee the timeout at the HTTP layer, configure a scoped HTTP client for your AI platform:
# config/packages/ai.yaml
framework:
http_client:
scoped_clients:
ai.timeout_client:
base_uri: 'https://api.openai.com'
timeout: 0.8
ai:
platform:
openai:
api_key: '%env(OPENAI_API_KEY)%'
http_client: 'ai.timeout_client'
🧾 Output formats
JSON (for APIs)
If the request includes Accept: application/json, the bundle returns structured JSON like:
{
"error_id": "a1b2c3d4e5f6g7h8",
"english_exception": "The database connection failed or a required table is missing.",
"probable_causes": ["..."],
"suggested_fixes": ["..."],
"confidence": 0.85
}
HTML (default)
Otherwise it renders an HTML page showing:
- Error ID
- AI explanation
- causes & suggested next steps
- confidence score
- original exception class/message
- a disclaimer that results are hypothese
🧠 Final thought
We’ve spent years making systems more resilient. We’ve improved logs, dashboards, alerts.
Maybe the next step is simpler:
Make systems better at explaining themselves.
Not to replace developers — but to help them think faster, with better context.