guzzle/guzzle · error · \InvalidArgumentException
Middleware not found: %s
Error message
Middleware not found: %s
What it means
before() and after() splice a middleware next to an existing named middleware via findByName(), which scans $stack for a tuple whose name (second element) matches. If no pushed/unshifted middleware was registered with that exact name, it throws InvalidArgumentException with the escaped name.
Source
Thrown at src/HandlerStack.php:246
public function __unserialize(array $data): void
{
$this->handler = null;
$this->stack = [];
$this->cached = null;
throw new \LogicException(static::class.' should never be unserialized');
}
private function findByName(string $name): int
{
foreach ($this->stack as $k => $v) {
if ($v[1] === $name) {
return $k;
}
}
throw new \InvalidArgumentException(\sprintf('Middleware not found: %s', DiagnosticValue::escape($name)));
}
/**
* Splices a function into the middleware list at a specific position.
*
* @param callable(callable&THandler): (callable&THandler) $middleware
*/
private function splice(string $findName, string $withName, callable $middleware, bool $before): void
{
$this->cached = null;
$idx = $this->findByName($findName);
$tuple = [$middleware, $withName];
if ($before) {
if ($idx === 0) {
\array_unshift($this->stack, $tuple);
} else {
$replacement = [$tuple, $this->stack[$idx]];View on GitHub (pinned to 9b200fc580)
Solutions
- Ensure the target middleware is pushed with the exact name first: $stack->push(Middleware::cookies(), 'cookies').
- Check the name spelling and case against the second argument used at push time.
- For the default stack, use HandlerStack::create() which registers http_errors, allow_redirects, auth, cookies, prepare_body.
Example fix
// before
$stack = new HandlerStack(new CurlHandler());
$stack->before('cookies', $myMiddleware); // throws: "Middleware not found: cookies"
// after
$stack = HandlerStack::create(); // registers default named middlewares
$stack->before('cookies', $myMiddleware); // now succeeds Defensive patterns
Strategy: validation
Validate before calling
// Guard before()/after() by checking the name exists:
$has = false;
foreach ($stack as $tuple) {
if (($tuple[1] ?? null) === $findName) { $has = true; break; }
}
if (! $has) {
throw new \InvalidArgumentException("Unknown middleware: $findName");
}
$stack->before($findName, $mw); Try / catch
try {
$stack->before($findName, $mw);
} catch (\InvalidArgumentException $e) {
// Either push the target middleware first, or append instead
$stack->push($mw);
} Prevention
- Use HandlerStack::create() to get the well-known default names (http_errors, allow_redirects, auth, cookies, prepare_body).
- Keep an enum/list of middleware names you have registered and reference it for before/after.
- Prefer push() with explicit names over fragile relative ordering when possible.
When it happens
Trigger: Calling $stack->before('cookies', $mw) or $stack->after('http_errors', $mw) when no middleware named 'cookies'/'http_errors' exists; typo in the name; calling before/after on a stack built with new HandlerStack() that never received HandlerStack::create()'s defaults.
Common situations: Registering a custom stack and assuming default names exist; name case mismatch; ordering before()/after() before the target middleware has been pushed.
Related errors
- GuzzleHttp\HandlerStack::remove(): Argument #1 ($remove) mus
- No handler has been specified
- Middleware must be callable
- Middleware must return a callable
- cookies must be an instance of GuzzleHttp\Cookie\CookieJarIn
AI-assisted analysis of guzzle/guzzle@9b200fc580 (2026-08-04).
Data as JSON: /data/errors/0e5afcde16122853.json.
Report an issue: GitHub.