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

  1. Call hasDefaultValue() first and only call getDefaultValue() when it returns true.
  2. For required arguments, treat the absence of a default as expected logic (no value available) rather than an error to unwrap.
  3. 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

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


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)