symfony/http-kernel · error · LogicException
Argument $ does not have a default value. Use "…
Error message
Argument $%s does not have a default value. Use "%s::hasDefaultValue()" to avoid this exception.
What it means
ArgumentMetadata::getDefaultValue() throws LogicException when the underlying controller/function argument has no default value. Symfony's argument metadata exposes hasDefaultValue() for checking first; calling getDefaultValue() on a required argument is a programmer error guarded by that exception.
Solutions
- Call hasDefaultValue() first and only call getDefaultValue() when it returns true.
- For required arguments, treat the absence of a default as expected logic (no value available) rather than an error to unwrap.
- If you control the signature, add an explicit default (e.g. int $id = 0) if a default actually makes sense.
Example fix
// before $default = $argument->getDefaultValue(); // after $default = $argument->hasDefaultValue() ? $argument->getDefaultValue() : null;
Defensive patterns
Strategy: type-guard
Validate before calling
if (!$argument->hasDefaultValue()) {
return null; // or handle required argument explicitly
} Type guard
function safeDefaultValue(\Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata $arg): mixed
{
return $arg->hasDefaultValue() ? $arg->getDefaultValue() : null;
} Try / catch
try {
$default = $argument->getDefaultValue();
} catch (\LogicException $e) {
$default = null; // argument is required, no default exists
} Prevention
- Always pair getDefaultValue() with hasDefaultValue() — the API contract requires it.
- Use IDE doc @throws hints to spot guarded accessors before calling them.
- In custom argument resolvers, branch on hasDefaultValue() before reading defaults.
- When writing reflection-based tooling, rely on ReflectionParameter::isDefaultValueAvailable() upstream too.
When it happens
Trigger: Calling getDefaultValue() on an ArgumentMetadata built from a parameter without a default (e.g. a route placeholder like {id} with no default in the action signature); argument resolvers or profiler code that skip the hasDefaultValue() check.
Common situations: Custom ArgumentValueResolver code reading default values for all arguments; debugging tools/profilers introspecting controller signatures; Symfony version change where getDefaultValue()'s contract became stricter (exception documented with @throws).
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Mapping variadic argument "$
- Could not resolve the "$
- The validation groups expression or closure must return a…
- Cannot mix virtual and HTTP requests.
- Request payload contains invalid "form" data.
AI-assisted analysis of symfony/http-kernel@aa3a39d728 (2026-09-13).
Data as JSON: /api/errors/5b8725763bd2bab7.
Report an issue: GitHub.
Appendix: source
Thrown at ControllerMetadata/ArgumentMetadata.php:89
}
/**
* Returns whether the argument accepts null values.
*/
public function isNullable(): bool
{
return $this->isNullable;
}
/**
* Returns the default value of the argument.
*
* @throws \LogicException if no default value is present; {@see self::hasDefaultValue()}
*/
public function getDefaultValue(): mixed
{
if (!$this->hasDefaultValue) {
throw new \LogicException(\sprintf('Argument $%s does not have a default value. Use "%s::hasDefaultValue()" to avoid this exception.', $this->name, __CLASS__));
}
return $this->defaultValue;
}
/**
* @param class-string $name
* @param self::IS_INSTANCEOF|0 $flags
*
* @return array<object>
*/
public function getAttributes(?string $name = null, int $flags = 0): array
{
if (!$name) {
return $this->attributes;
}
return $this->getAttributesOfType($name, $flags);View on GitHub (pinned to aa3a39d728)