Full disclosure: Evidence gathering and issue writing was done with the help of Claude Code
Version: Symfony Language Tools 0.17.1
Summary
When a runtime metadata section fails, the only text produced anywhere is the section name in a
fixed sentence. The throwable — class, message, file, line — is dropped at the catch site and
never recorded, logged or displayed.
SymfonyLspBridgeContext::addError() accepts only the section name, so there is no parameter a
cause could be passed in (bridge/context.php:473):
public function addError(string $section): void
{
$this->errors[] = [
'section' => $section,
'message' => sprintf('Unable to load the "%s" runtime metadata section.', $section),
];
}
and every catch site discards the throwable by not binding it (bridge.php:138, and identically
in sections/twig.php:39, sections/security.php:23, sections/container.php:8,
sections/routes.php:8, …):
} catch (Throwable) {
$context->addError($sectionName);
}
Reproduction
Make one section fail with a distinctive message — a Twig extension that throws when the
section's debug:twig runs:
public function getFunctions(): array
{
throw new \RuntimeException('deliberate twig section failure');
}
deliberate twig section failure then appears nowhere: not in the bridge payload, not on its
stderr (empty), not in any output the tooling produces. All that is reported is:
Unable to load the "twig" runtime metadata section.
Why it matters
A section failing inside an otherwise successful run is the common case, because the bridge exits
0 when that happens — so the situation users are most likely to hit produces the least
information.
Diagnosing our own case meant patching the extracted bridge to print the throwable and re-running
it by hand; the cause was several frames deep and not guessable from the section name. Anyone
whose project trips a section faces the same reverse-engineering to learn whether the problem is
their code, their configuration, or the tool.
Expected
Record the throwable's class and message, ideally the first frames too, and surface them wherever
the failure is reported. If project output must stay out of the log by default, an opt-in flag or
a dedicated channel would still make diagnosis possible.
Full disclosure: Evidence gathering and issue writing was done with the help of Claude Code
Version: Symfony Language Tools 0.17.1
Summary
When a runtime metadata section fails, the only text produced anywhere is the section name in a
fixed sentence. The throwable — class, message, file, line — is dropped at the catch site and
never recorded, logged or displayed.
SymfonyLspBridgeContext::addError()accepts only the section name, so there is no parameter acause could be passed in (
bridge/context.php:473):and every catch site discards the throwable by not binding it (
bridge.php:138, and identicallyin
sections/twig.php:39,sections/security.php:23,sections/container.php:8,sections/routes.php:8, …):Reproduction
Make one section fail with a distinctive message — a Twig extension that throws when the
section's
debug:twigruns:deliberate twig section failurethen appears nowhere: not in the bridge payload, not on itsstderr (empty), not in any output the tooling produces. All that is reported is:
Why it matters
A section failing inside an otherwise successful run is the common case, because the bridge exits
0 when that happens — so the situation users are most likely to hit produces the least
information.
Diagnosing our own case meant patching the extracted bridge to print the throwable and re-running
it by hand; the cause was several frames deep and not guessable from the section name. Anyone
whose project trips a section faces the same reverse-engineering to learn whether the problem is
their code, their configuration, or the tool.
Expected
Record the throwable's class and message, ideally the first frames too, and surface them wherever
the failure is reported. If project output must stay out of the log by default, an opt-in flag or
a dedicated channel would still make diagnosis possible.