Error Identifier: method.impureOverridePureUnlessParameterPassed

← Back to method.*

Every error reported by PHPStan has an error identifier. Here’s a list of all error identifiers. In PHPStan Pro you can see the error identifier next to each error and filter errors by their identifiers.

Code example #

<?php declare(strict_types = 1);

interface PureUnlessParent
{

	/**
	 * @param-out int $count
	 * @pure-unless-parameter-passed $count
	 */
	public function replace(string $subject, int &$count = 0): string;

}

class ImpureChild implements PureUnlessParent
{

	/**
	 * @phpstan-impure
	 */
	public function replace(string $subject, int &$count = 0): string // ERROR: Impure method ImpureChild::replace() overrides method PureUnlessParent::replace() marked @pure-unless-parameter-passed.
	{
		echo 'side effect';
		$count = 1;

		return $subject;
	}

}

Why is it reported? #

The @pure-unless-parameter-passed tag declares that the parent method is pure unless an argument is passed for the named by-reference parameter. When the caller omits that argument, the call has no side effects; when the caller passes it, the method writes into the caller’s variable. Apart from writing through that parameter, the method body is expected to have no side effects.

An overriding method marked @phpstan-impure (or living in a class marked @phpstan-all-methods-impure) breaks this contract: it has side effects even when the by-reference argument is omitted. Code that relies on the parent’s conditional purity — for example calling replace($subject) without $count inside a pure function — would then be reasoning about a method that is always impure.

This check is part of Bleeding Edge.

How to fix it #

Remove @phpstan-impure from the child and keep its body free of side effects other than writing to the flagged by-reference parameter, so it honors the inherited @pure-unless-parameter-passed contract:

 class ImpureChild implements PureUnlessParent
 {

-	/**
-	 * @phpstan-impure
-	 */
 	public function replace(string $subject, int &$count = 0): string
 	{
-		echo 'side effect';
 		$count = 1;

 		return $subject;
 	}

 }

If the child genuinely needs side effects, the parent’s purity contract cannot hold across all implementations. Remove @pure-unless-parameter-passed from the parent method:

 interface PureUnlessParent
 {

 	/**
 	 * @param-out int $count
-	 * @pure-unless-parameter-passed $count
 	 */
 	public function replace(string $subject, int &$count = 0): string;

 }

How to ignore this error #

You can use the identifier method.impureOverridePureUnlessParameterPassed to ignore this error using a comment:

// @phpstan-ignore method.impureOverridePureUnlessParameterPassed
codeThatProducesTheError();

You can also use only the identifier key to ignore all errors of the same type in your configuration file in the ignoreErrors parameter:

parameters:
	ignoreErrors:
		-
			identifier: method.impureOverridePureUnlessParameterPassed

Rules that report this error #

  • PHPStan\Rules\Methods\MethodSignatureRule [1]
  • PHPStan\Rules\Methods\OverridingMethodRule [1]
Theme
© 2026 PHPStan s.r.o.