the-benchmarker/web-frameworks · error · InvalidArgumentException

Parameter ' ' of :: should not be null

Error message

Parameter '{$definition->getMeta('name')}' of {$controller}::{$action} should not be null

What it means

Hyperf's FastServer route-parameter parser (parseParameters) builds the argument list for a controller action. When a required request parameter has no value, no default, does not allow null, and its name does not resolve to a container entry, it throws this InvalidArgumentException because the action cannot be invoked with a null it declared mandatory.

Solutions

  1. Have the client send the missing parameter, or make it optional by allowing null or adding a defaultValue in the parameter definition
  2. Verify the request actually contains the parameter under the exact name the action expects (check typos and content-type handling)
  3. Change the action signature so the parameter is nullable or has a documented default when it is legitimately optional
  4. Return a clean 400 validation response instead of a 500 by validating input before dispatch or mapping this exception in the exception handler

Example fix

// before
public function show(string $id) { ... } // client omits id

// after
public function show(?string $id = null) {
    if ($id === null) {
        throw new HyperfValidationValidationException('id is required');
    }
    ...
}
Defensive patterns

Strategy: validation

Validate before calling

// before dispatching, ensure required params are present
const REQUIRED: array<string, string> = ['id' => 'query', 'name' => 'body'];
foreach (REQUIRED as $name => $where) {
    $value = $where === 'query' ? $request->getQueryParam($name) : $request->getParsedBody()[$name] ?? null;
    if ($value === null || $value === '') {
        throw new \Hyperf\HttpMessage\Exception\BadRequestHttpException("Missing required parameter: {$name}");
    }
}

Type guard

function hasParam(?string $value): bool
{
    return $value !== null && $value !== '';
}

Try / catch

try {
    $response = $this->handleFound($route, $request);
} catch (\InvalidArgumentException $e) {
    if (str_contains($e->getMessage(), 'should not be null')) {
        return $responseFactory->createResponse(400)->withJson(['error' => $e->getMessage()]);
    }
    throw $e;
}

Prevention

When it happens

Trigger: A client calls an HTTP route whose action signature declares a parameter with a definition that (a) received no value in the request, (b) has no defaultValue in its metadata, (c) does not allowNull(), and (d) is not a container-managed service — reached via handleFound -> parseParameters.

Common situations: Client omits a required query/body parameter; frontend sends a different parameter name than the action expects (typo or renamed field); middleware stripped the value; a new required parameter was added to the action while old clients still call the endpoint without it.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of the-benchmarker/web-frameworks@3795a31d72 (2026-09-15). Data as JSON: /api/errors/9ece72e08e24653f. Report an issue: GitHub.

Appendix: source

Thrown at php/hyperf/app/Kernel/FastServer.php:143

     * Parse the parameters of method definitions, and then bind the specified arguments or
     * get the value from DI container, combine to a argument array that should be injected
     * and return the array.
     */
    protected function parseParameters(string $controller, string $action, array $arguments): array
    {
        $injections = [];
        $definitions = $this->methodDefinitionCollector->getParameters($controller, $action);
        foreach ($definitions ?? [] as $pos => $definition) {
            $value = $arguments[$pos] ?? $arguments[$definition->getMeta('name')] ?? null;
            if ($value === null) {
                if ($definition->getMeta('defaultValueAvailable')) {
                    $injections[] = $definition->getMeta('defaultValue');
                } elseif ($definition->allowsNull()) {
                    $injections[] = null;
                } elseif ($this->container->has($definition->getName())) {
                    $injections[] = $this->container->get($definition->getName());
                } else {
                    throw new \InvalidArgumentException("Parameter '{$definition->getMeta('name')}' "
                        . "of {$controller}::{$action} should not be null");
                }
            } else {
                $injections[] = $this->normalizer->denormalize($value, $definition->getName());
            }
        }

        return $injections;
    }
}

View on GitHub (pinned to 3795a31d72)