26 KiB
Issue types
AbstractInstantiation
Emitted when an attempt is made to instatiate an abstract class:
abstract class A {}
new A();
AssignmentToVoid
Emitted when assigning from a function that returns void
:
function foo() : void {}
$a = foo();
CircularReference
Emitted when a class references itself as one of its parents
class A extends B {}
class B extends A {}
ContinueOutsideLoop
Emitted when encountering a continue
statement outside a loop context.
DeprecatedClass
Emitted when creating a new instance of a deprecated class:
/** @deprecated */
class A {}
new A();
DeprecatedMethod
Emitted when calling a deprecated method on a given class:
class A {
/** @deprecated */
public function foo() : void {}
}
(new A())->foo();
DeprecatedProperty
Emitted when getting/setting a deprecated property of a given class
class A {
/**
* @deprecated
* @var ?string
*/
public $foo;
}
(new A())->foo = 5;
DuplicateClass
Emitted when a class is defined twice
class A {}
class A {}
DuplicateParam
Emitted when a class param is defined twice
class A {
/** @var ?string */
public $foo;
/** @var ?string */
public $foo;
}
EmptyArrayAccess
Emitted when attempting to access a value on an empty array
$a = [];
$b = $a[0];
FalsableReturnStatement
Emitted if a return statement contains a false value, but the function return type does not allow false
function foo() : string {
if (rand(0, 1)) {
return "foo";
}
return false; // emitted here
}
ForbiddenCode
Emitted when Psalm encounters a var_dump, exec or similar expression that may make your code more vulnerable
var_dump($foo);
ImplementedReturnTypeMismatch
Emitted when a class that inherits another, or implements an interface, has docblock return type that's entirely different to the parent. Subclasses of the parent return type are permitted, in docblocks.
class A {
/** @return bool */
public function foo() {
return true;
}
}
class B extends A {
/** @return string */
public function foo() {
return "hello";
}
}
ImplicitToStringCast
Emitted when implictly converting an object with a __toString
method to a string
class A {
public function __toString() {
return "foo";
}
}
function takesString(string $s) : void {}
takesString(new A);
InaccessibleClassConstant
Emitted when a public/private class constant is not accessible from the calling context
class A {
protected const FOO = 'FOO';
}
echo A::FOO;
InaccessibleMethod
Emitted when attempting to access a protected/private method from outside its available scope
class A {
protected function foo() : void {}
}
echo (new A)->foo();
InaccessibleProperty
Emitted when attempting to access a protected/private property from outside its available scope
class A {
/** @return string */
protected $foo;
}
echo (new A)->foo;
InvalidArgument
Emitted when a supplied function/method argument is incompatible with the method signature or docblock one.
class A {}
function foo(A $a) : void {}
foo("hello");
InvalidArrayAccess
Emitted when attempting to access an array offset on a value that does not permit it
$arr = 5;
echo $arr[0];
InvalidArrayAssignment
Emitted when attempting to assign a value on a non-array
$arr = 5;
$arr[0] = 3;
InvalidArrayOffset
Emitted when when attempting to access an array using a value that's not a valid offet for that array
$a = [5, 20, 18];
echo $a["hello"];
InvalidCast
Emitted when attempting to cast a value that's not castable
class A {}
$a = new A();
$b = (string)$a;
InvalidCatch
Emitted when trying to catch a class/interface that doesn't extend Exception
or implement Throwable
class A {}
try {
$worked = true;
}
catch (A $e) {}
InvalidClass
Emitted when referencing a class with the wrong casing
class Foo {}
(new foo());
InvalidClone
Emitted when trying to clone a value that's not cloneable
$a = "hello";
$b = clone $a;
InvalidDocblock
Emitted when there's an error in a docblock type
/** @var array() */
$a = [];
InvalidFalsableReturnType
Emitted when a function can return a nullable value, but its given return type says otherwise
function foo() : string {
if (rand(0, 1)) {
return "foo";
}
return false;
}
InvalidFunctionCall
Emitted when calling a function on a non-callable variable
$a = 5;
$b = $a();
InvalidGlobal
Emitted when there's a reference to the global keyword where it's not expected
global $e;
InvalidIterator
Emitted when trying to iterate over a value that's not iterable
$a = 5;
foreach ($a as $b) {}
InvalidMethodCall
Emitted when attempting to call a method on a non-object
$a = 5;
$a->foo();
InvalidNullableReturnType
Emitted when a function can return a nullable value, but its given return type says otherwise
function foo() : string {
if (rand(0, 1)) {
return "foo";
}
return null;
}
InvalidOperand
Emitted when using something as an operand that is unexected
class A {}
echo (new A) . ' ';
InvalidParamDefault
Emitted when a function parameter default clashes with the type Psalm expects the param to be
function foo(int $i = false) : void {}
InvalidPassByReference
Emitted when passing a non-variable to a function that expects a by-ref variable
function foo(array &$arr) : void {}
foo([0, 1, 2]);
InvalidPropertyAssignment
Emitted when attempting to assign a property to a non-object
$a = "foo";
$a->bar = "bar";
InvalidPropertyFetch
Emitted when attempting to get a property from a non-object
$a = "foo";
echo $a->bar;
InvalidReturnStatement
Emitted when a function return statement is incorrect
function foo() : string {
return 5; // emitted here
}
InvalidReturnType
Emitted when a function’s signature return type is incorrect (often emitted with `InvalidReturnStatement`)
function foo() : int {
if (rand(0, 1)) {
return "hello";
}
return 5;
}
InvalidScalarArgument
Emitted when a scalar value is passed to a method that expected another scalar type
function foo(int $i) : void {}
function bar(string $s) : void {
if (is_numeric($s)) {
foo($s);
}
}
InvalidScope
Emitted when referring to $this
outside a class
echo $this;
InvalidStaticInvocation
Emitted when trying to call an instance function statically
class A {
/** @var ?string */
public $foo;
public function bar() : void {
echo $this->foo;
}
}
A::bar();
InvalidThrow
Emitted when trying to throw a class that doesn't extend Exception
or implement Throwable
class A {}
throw new A();
InvalidToString
Emitted when a __toString
method does not always return a string
class A {
public function __toString() {
return true;
}
}
LessSpecificReturnStatement
Emitted when a return statement is more general than the return type given for the function
class A {}
class B extends A {}
function foo() : B {
return new A(); // emitted here
}
LessSpecificReturnType
Emitted when a return type covers more possibilities than the function itself
function foo() : ?int {
return 5;
}
LoopInvalidation
Emitted when logic inside a loop invalidates one of the conditionals of the loop
for ($i = 0; $i < 10; $i++) {
$i = 5;
}
MethodSignatureMismatch
Emitted when a method parameter differs from a parent method parameter, or if there are fewer parameters than the parent method
class A {
public function foo(int $i) : void {}
}
class B extends A {
public function foo(string $s) : void {}
}
MismatchingDocblockParamType
Emitted when an @param
entry in a function’s docblock doesn’t match the param typehint,
class A {}
class B {}
/**
* @param B $b // emitted here
*/
function foo(A $b) : void {}
This, however, is fine:
class A {}
class B extends A {}
/**
* @param B
*/
function foo(A $b) : void {}
MismatchingDocblockReturnType
Emitted when an @return
entry in a function’s docblock doesn’t match the function return typehint
class A {}
class B {}
/**
* @return B // emitted here
*/
function foo() : A {
return new A();
}
This, however, is fine:
class A {}
class B extends A {}
/**
* @return B // emitted here
*/
function foo() : A {
return new B();
}
MismatchingDocblockParamType
Emitted when an @param
entry in a function’s docblock doesn’t match the param typehint
/**
* @param int $b
*/
function foo(string $b) : void {}
MisplacedRequiredParam
Emitted when a required param is before a param that is not required. Included in Psalm because it is an E_WARNING in PHP
function foo(int $i = 5, string $j) : void {}
MissingClosureReturnType
Emitted when a closure lacks a return type
$a = function() {
return "foo";
};
MissingConstructor
Emitted when non-null properties without default values are defined in a class without a __construct
method
class A {
/** @var string */
public $foo;
}
MissingDocblockType
Emitted when a docblock is present, but the type is missing or badly formatted
/** @var $a */
$a = [];
MissingFile
Emitted when using include
or require
on a file that does not exist
require("nonexistent.php");
MissingPropertyType
Emitted when a property is defined on a class without a type
class A {
public $foo;
}
MissingReturnType
Emitted when a function doesn't have a return type defined
function foo() {
return "foo";
}
MixedArgument
Emitted when Psalm cannot determine the type of an argument
function takesInt(int $i) : void {}
takesInt($_GET['foo']);
MixedArrayAccess
Emitted when trying to access an array offset on a value whose type Psalm cannot determine
echo $_GET['foo'][0];
MixedArrayAssignment
Emitted when trying to assign a value to an array offset on a value whose type Psalm cannot determine
$_GET['foo'][0] = "5";
MixedArrayOffset
Emitted when attempting to access an array offset where Psalm cannot determine the offset type
echo [1, 2, 3][$_GET['foo']];
MixedAssignment
Emitted when assigning a variable to a value for which Psalm cannot infer a type
$a = $_GET['foo'];
MixedInferredReturnType
Emitted when Psalm cannot determine a function's return type
function foo() : int {
return $_GET['foo'];
}
MixedMethodCall
Emitted when calling a method on a value that Psalm cannot infer a type for
/** @param mixed $a */
function foo($a) : void {
$a->foo();
}
MixedOperand
Emitted when Psalm cannot infer a type for an operand in any calculated expression
echo $_GET['foo'] + "hello";
MixedPropertyAssignment
Emitted when assigning a property to a value for which Psalm cannot infer a type
/** @param mixed $a */
function foo($a) : void {
$a->foo = "bar";
}
MixedPropertyFetch
Emitted when retrieving a property on a value for which Psalm cannot infer a type
/** @param mixed $a */
function foo($a) : void {
echo $a->foo;
}
MixedReturnStatement
Emitted when Psalm cannot determine the type of a given return statement
function foo() : int {
return $_GET['foo']; // emitted here
}
MixedStringOffsetAssignment
Emitted when assigning a value on a string using a value for which Psalm cannot infer a type
"hello"[$_GET['foo']] = "h";
MixedTypeCoercion
Emitted when Psalm cannot be sure that part of an array/iterabble argument's type constraints can be fulfilled
function foo(array $a) : void {
takesStringArray($a);
}
/** @param string[] $a */
function takesStringArray(array $a) : void {}
MoreSpecificImplementedReturnType
Emitted when a class implements an interface method but its return type is less specific than the interface method return type
class A {}
class B extends A {}
interface I {
/** @return B[] */
public function foo();
}
class D implements I {
/** @return A[] */
public function foo() {
return [new A, new A];
}
}
MoreSpecificReturnType
Emitted when the declared return type for a method is more specific than the inferred one (emitted in the same methods that LessSpecificReturnStatement
is)
class A {}
class B extends A {}
function foo() : B {
/** @psalm-suppress LessSpecificReturnStatement */
return new A();
}
NoInterfaceProperties
Emitted when trying to fetch a property on an interface as interfaces, by definition, do not have definitions for properties.
interface I {}
class A implements I {
/** @var ?string */
public $foo;
}
function bar(I $i) : void {
if ($i->foo) {}
}
NonStaticSelfCall
Emitted when
NullableReturnStatement
Emitted if a return statement contains a null value, but the function return type is not nullable
function foo() : string {
if (rand(0, 1)) {
return "foo";
}
return null; // emitted here
}
NullArgument
Emitted when calling a function with a null value argument when the function does not expect it
function foo(string $s) : void {}
foo(null);
NullArrayAccess
Emitted when trying to access an array value on null
$arr = null;
echo $arr[0];
NullArrayOffset
Emitted when trying to access an array offset with null
$arr = ['' => 5, 'foo' => 1];
echo $arr[null];
NullFunctionCall
Emitted when trying to use null
as a callable
$arr = null;
echo $arr();
NullIterator
Emitted when iterating over null
foreach (null as $a) {}
NullOperand
Emitted when using null
as part of an operation (e.g. +
, .
, ^
etc.`)
echo null . 'hello';
NullPropertyAssignment
Emitted when trying to set a property on null
$a = null;
$a->foo = "bar";
NullPropertyFetch
Emitted when trying to fetch a property on a null
value
$a = null;
echo $a->foo;
NullReference
Emitted when attempting to call a method on null
$a = null;
$a->foo();
OverriddenMethodAccess
Emitted when a method is less accessible than its parent
class A {
public function foo() : void {}
}
class B extends A {
protected function foo() : void {}
}
ParadoxicalCondition
Emitted when a paradox is encountered in your programs logic that could not be caught by RedundantCondition
function foo(?string $a) : ?string {
if ($a) return $a;
if ($a) echo "cannot happen";
}
ParentNotFound
Emitted when using parent::
in a class without a parent class.
class A {
public function foo() : void {
parent::foo();
}
}
PossiblyFalseArgument
Emitted when a function argument is possibly false
, but the function doesn’t expect false
. This is distinct from a function argument is possibly bool
, which results in PossiblyInvalidArgument
.
function foo(string $s) : void {
$a_pos = strpos($s, "a");
echo substr($s, $a_pos);
}
PossiblyFalseReference
Emitted when making a method call on a value than might be false
class A {
public function bar() : void {}
}
/** @return A|false */
function foo() {
return rand(0, 1) ? new A : false;
}
foo()->bar();
PossiblyInvalidArgument
Emitted when
/** @return string|int */
function foo() {
return rand(0, 1) ? 5 : "i";
}
function bar(int $i) : void {}
bar(foo());
PossiblyInvalidArrayAccess
Emitted when attempting to access an array offset on a value that may not be an array
$arr = rand(0, 1) ? 5 : [4, 3, 2, 1];
echo $arr[0];
PossiblyInvalidArrayAssignment
Emitted when attempting to assign an array offset on a value that may not be an array
$arr = rand(0, 1) ? 5 : [4, 3, 2, 1];
$arr[0] = "hello";
PossiblyInvalidArrayOffset
Emitted when it’s possible that the array offset is not applicable to the value you’re trying to access.
$arr = rand(0, 1) ? ["a" => 5] : "hello";
echo $arr[0];
PossiblyInvalidFunctionCall
Emitted when trying to call a function on a value that may not be callable
$a = rand(0, 1) ? 5 : function() : int { return 5; };
$b = $a();
PossiblyInvalidMethodCall
Emitted when trying to call a method on a value that may not be an object
class A {
public function bar() : void {}
}
/** @return A|int */
function foo() {
return rand(0, 1) ? new A : 5;
}
foo()->bar();
PossiblyInvalidPropertyAssignment
Emitted when trying to assign a property on a value that may not be an object or may be an object that doesn’t have the desired property.
class A {
/** @var ?string */
public $bar;
}
/** @return A|int */
function foo() {
return rand(0, 1) ? new A : 5;
}
$a = foo();
$a->bar = "5";
PossiblyInvalidPropertyFetch
Emitted when trying to fetch a property on a value that may not be an object or may be an object that doesn’t have the desired property.
class A {
/** @var ?string */
public $bar;
}
/** @return A|int */
function foo() {
return rand(0, 1) ? new A : 5;
}
$a = foo();
echo $a->bar;
PossiblyNullArgument
Emitted when calling a function with a value that’s possibly null when the function does not expect it
function foo(string $s) : void {}
foo(rand(0, 1) ? "hello" : null);
PossiblyNullArrayAccess
Emitted when trying to access an array offset on a possibly null value
function foo(?array $a) : void {
echo $a[0];
}
PossiblyNullArrayAssignment
Emitted when trying to set a value on a possibly null array
function foo(?array $a) : void {
$a[0] = "5";
}
PossiblyNullArrayOffset
Emitted when trying to access a value on an array using a possibly null offset
function foo(?int $a) : void {
echo [1, 2, 3, 4][$a];
}
PossiblyNullFunctionCall
Emitted when trying to call a function on a value that may be null
function foo(?callable $a) : void {
$a();
}
PossiblyNullIterator
Emitted when trying to iterate over a value that may be null
function foo(?array $arr) : void {
foreach ($arr as $a) {}
}
PossiblyNullOperand
Emitted when using a possibly null
value as part of an operation (e.g. +
, .
, ^
etc.`)
function foo(?int $a) : void {
echo $a + 5;
}
PossiblyNullPropertyAssignment
Emitted when trying to assign a property to a possibly null object
class A {
/** @var ?string */
public $foo;
}
function foo(?A $a) : void {
$a->foo = "bar";
}
PossiblyNullPropertyFetch
Emitted when trying to fetch a property on a possibly null object
class A {
/** @var ?string */
public $foo;
}
function foo(?A $a) : void {
echo $a->foo;
}
PossiblyNullReference
Emitted when trying to call a method on a possibly null value
class A {
public function bar() : void {}
}
function foo(?A $a) : void {
$a->bar();
}
PossiblyUndefinedGlobalVariable
Emitted when trying to access a variable in the global scope that may not be defined
if (rand(0, 1)) {
$a = 5;
}
echo $a;
PossiblyUndefinedMethod
Emitted when trying to access a method that may not be defined on the object
class A {
public function bar() : void {}
}
class B {}
$a = rand(0, 1) ? new A : new B;
$a->bar();
PossiblyUndefinedVariable
Emitted when trying to access a variable in function scope that may not be defined
function foo() : void {
if (rand(0, 1)) {
$a = 5;
}
echo $a;
}
PossiblyUnusedMethod
Emitted when --find-dead-code
is turned on and Psalm cannot find any calls to a given class method
class A {
public function foo() : void {}
public function bar() : void {}
}
(new A)->foo();
PossiblyUnusedParam
Emitted when --find-dead-code
is turned on and Psalm cannot find any uses of a particular parameter in a public/protected method
class A {
public function foo(int $a, int $b) : int {
return $a + 4;
}
}
PropertyNotSetInConstructor
Emitted when a non-null property without a default value is declared but not set in the class’s constructor
class A {
/** @var string */
public $foo;
public function __construct() {}
}
RawObjectIteration
Emitted when iterating over an object’s properties. This issue exists because it may be undesired behaviour (e.g. you may have meant to iterate over an array)
class A {
/** @var string */
public $foo;
/** @var string */
public $bar;
}
function takesA(A $a) {
foreach ($a as $property) {}
}
RedundantCondition
Emitted when conditional is redundant given previous assertions
class A {}
function foo(?A $a) : ?A {
if ($a) return $a;
if ($a) echo "cannot happen";
}
ReferenceConstraintViolation
Emitted when changing the type of a pass-by-reference variable
function foo(string &$a) {
$a = 5;
}
ReservedWord
Emitted when using a reserved word as a class name
function foo(resource $res) : void {}
TooFewArguments
Emitted when calling a function with fewer arguments than the function has parameters
function foo(string $a) : void {}
foo();
TooManyArguments
Emitted when calling a function with more arguments than the function has parameters
function foo(string $a) : void {}
foo("hello", 4);
TypeCoercion
Emitted when calling a function with an argument which has a less specific type than the function expects
class A {}
class B extends A {}
function takesA(A $a) : void {
takesB($a);
}
function takesB(B $b) : void {}
TypeDoesNotContainNull
Emitted when checking a non-nullable type for null
$a = "hello";
if ($a === null) {}
TypeDoesNotContainType
Emitted checking whether one value has a type or value that is impossible given its currently-known type
$a = "hello";
if ($a === 5) {}
UndefinedClass
Emitted when referencing a class that doesn’t exist
$a = new A();
UndefinedConstant
Emitted when referencing a constant that doesn’t exist
echo FOO_BAR;
UndefinedFunction
Emitted when referencing a function that doesn't exist
foo();
UndefinedGlobalVariable
Emitted when referencing a variable that doesn't exist
echo $a;
UndefinedMethod
Emitted when calling a method that doesn’t exist
class A {}
A::foo();
UndefinedPropertyAssignment
Emitted when assigning a property on an object that doesn’t have that property defined
class A {}
$a = new A();
$a->foo = "bar";
UndefinedPropertyFetch
Emitted when getting a property on an object that doesn’t have that property defined
class A {}
$a = new A();
echo $a->foo;
UndefinedThisPropertyAssignment
Emitted when assigning a property on an object in one of that object’s methods when no such property exists
class A {
function foo() {
$this->foo = "bar";
}
}
UndefinedThisPropertyFetch
Emitted when getting a property for an object in one of that object’s methods when no such property exists
class A {
function foo() {
echo $this->foo;
}
}
UndefinedTrait
Emitted when referencing a trait that doesn’t exist
class A {
use T;
}
UndefinedVariable
Emitted when referencing a variable that doesn't exist in a given function’s scope
function foo() {
echo $a;
}
UnevaluatedCode
Emitted when --find-dead-code
is turned on and Psalm encounters code that will not be evaluated
function foo() : void {
return;
$a = "foo";
}
UnimplementedAbstractMethod
Emitted when a class extends another, but does not implement all of its abstract methods
abstract class A {
abstract public function foo();
}
class B extends A {}
UnimplementedInterfaceMethod
Emitted when a class implements
an interface but does not implement all of its methods
interface I {
public function foo();
}
class A implements I {}
UnrecognizedExpression
Emitted when Psalm encounters an expression that it doesn't know how to handle. This should never happen.
UnrecognizedStatement
Emitted when Psalm encounters a code construct that it doesn't know how to handle. This should never happen.
UnresolvableInclude
Emitted when Psalm cannot figure out what specific file is being included/required by PHP.
function requireFile(string $s) : void {
require_once($s);
}
UntypedParam
Emitted when a function paramter has no type information associated with it
function foo($a) : void {}
UnusedClass
Emitted when --find-dead-code
is turned on and Psalm cannot find any uses of a given class
class A {}
class B {}
$a = new A();
UnusedMethod
Emitted when --find-dead-code
is turned on and Psalm cannot find any uses of a given private method or function
class A {
public function __construct() {
$this->foo();
}
private function foo() : void {}
private function bar() : void {}
}
new A();
UnusedParam
Emitted when --find-dead-code
is turned on and Psalm cannot find any uses of a particular parameter in a private method or function
function foo(int $a, int $b) : int {
return $a + 4;
}
UnusedVariable
Emitted when --find-dead-code
is turned on and Psalm cannot find any references to a variable, once instantiated
function foo() : void {
$a = 5;
$b = 4;
echo $b;
}