Note
Diagnostic codes are stable identifiers. Once assigned, a code number always refers to the same
diagnostic, even across compiler versions. The canonical list of codes lives in
Tyhp/Domain/Exceptions/MessageCode.cs.
Tier 1 · Story 14Complete
This page is the comprehensive index of Tyhp compiler diagnostic codes. Every entry is
generated from the compiler's code registry (MessageCode.cs) and the localized short-message
catalog (.resx), so the message text always matches what the compiler emits.
Diagnostic codes are stable identifiers. Once assigned, a code number always refers to the same
diagnostic, even across compiler versions. The canonical list of codes lives in
Tyhp/Domain/Exceptions/MessageCode.cs.
Run tyhp --explain TYHP#### (or tyhp explain ####) to print the
long-form explanation for any code. That command reads the same dynamic catalog as this page.
tyhp --explain TYHP4008
tyhp explain 4008
tyhp explain --code=TYHP3003
Parser errors occur during the ANTLR4 lexing and parsing phase when the compiler encounters syntax it cannot understand.
TYHP1001 (Error)ParserUnknownError. Message: Unknown parser error: {0}.
A catch-all for parser/lexer errors that do not match a more specific code. The {0} placeholder contains the underlying error message from the ANTLR4 parser.
<?tyhp
// Invalid token that confuses the lexer
class #invalid { }
Fix: Examine the indicated line and column for syntax errors. Ensure all tokens are valid Tyhp/PHP syntax.
TYHP1002 (Error)ParserUnexpectedError. Message: Unexpected token .{0} at position {1}
The parser encountered a token it did not expect at the current position. This usually indicates a missing semicolon, unmatched brace, or misplaced keyword.
<?tyhp
function greet(string $name) string {
// Missing colon before return type ^^^
return "Hello, $name";
}
Fix: Check the line for missing punctuation (semicolons, colons, braces, parentheses) or misplaced keywords. The correct syntax above is function greet(string $name): string.
TYHP1003 (Error)ParserCompileAborted. Message: Compilation aborted: {0}.
The parser encountered too many errors and aborted processing for the current file. Earlier errors in the same file typically cause this.
Fix: Fix the earlier parser errors in the same file and recompile. Once the foundational syntax issues are resolved, this error will no longer appear.
TYHP1004 (Error)LexerCloseTagNotAllowedInTaglessMode. Message: Closing tag .?> is not allowed when source.tagless is enabled
Run tyhp --explain TYHP1004 for the long-form explanation.
Visitor errors occur during parse-tree to AST conversion when the visitor encounters an unexpected structure or unsupported construct.
TYHP2001 (Error)VisitorUnknownError. Message: Unknown visitor error.
A catch-all for unexpected errors during AST generation. This typically indicates an internal compiler issue.
Fix: If you encounter this error, simplify the code near the indicated location and try again. If the error persists, please report it as a compiler bug.
TYHP2002 (Error)VisitorUnexpectedAlternative. Message: Unexpected grammar alternative .{1} in rule {0}
The visitor hit an unexpected grammar alternative while walking the parse tree (a production the AST builder does not handle). This may occur with unusual or edge-case syntax combinations.
Fix: Simplify the expression or statement. If the syntax is valid PHP/Tyhp, this may indicate a compiler limitation -- please report it.
TYHP2003 (Error)VisitorMissingRequiredNode. Message: Required AST node missing in rule .{0}
A required component of a language construct was not found in the parse tree. This often results from incomplete or malformed syntax.
<?tyhp
// Missing class body
class User
Fix: Ensure the construct is syntactically complete. Classes need bodies ({ }), functions need parameter lists and bodies, etc.
TYHP2004 (Error)VisitorUnsupportedConstruct. Message: Language construct .{0} is not yet supported
The code uses a PHP language construct that the Tyhp compiler does not yet support.
Fix: Use an alternative approach that is supported by the compiler. Check the Tyhp documentation for supported constructs and any known limitations.
Binder errors occur during symbol resolution and scope management.
TYHP3001 (Error, Warning)BinderUnknownError. Message: Unknown binder error: {0}.
A catch-all for unexpected errors during the binding phase.
Fix: If you encounter this error, please report it as a compiler bug with a minimal reproduction.
TYHP3002 (Error)BinderDuplicateSymbolDeclaration. Message: Duplicate declaration of symbol .{0}
Two declarations with the same name exist in the same scope. This includes classes, functions, constants, and variables declared at the same scope level.
<?tyhp
class User { }
class User { } // Error: Duplicate declaration of symbol 'User'
Fix: Rename one of the duplicate declarations, or remove the duplicate. If the declarations are in different files, ensure they are in different namespaces.
TYHP3003 (Error)BinderSymbolNotFound. Message: Symbol .{0} is not found
A referenced class, function, constant, variable, or other symbol could not be resolved in any accessible scope.
<?tyhp
function process(UnknownType $item): void {
// Error: Symbol 'UnknownType' not found
}
Fix: Add a use statement to import the symbol, check for typos in the name, verify the symbol is defined in a loaded tyhpdef file, or ensure the file defining the symbol is included in the project.
TYHP3004 (Error)BinderInvalidSymbolTypeForParent. Message: Symbol type .{0} is not valid for parent scope {1}
A symbol was declared in a scope where that type of declaration is not allowed.
Fix: Move the declaration to an appropriate scope. For example, class declarations belong at the namespace level, not inside function bodies.
TYHP3005 (Error)BinderInvalidFileScopeArgument. Message: Invalid argument for file scope.
An internal error indicating an invalid configuration was passed to the file scope during binding.
TYHP3006 (Error)BinderCircularInheritance. Message: Circular inheritance detected involving .{0}
A class or interface directly or indirectly extends or implements itself, creating an inheritance cycle.
<?tyhp
class A extends B { }
class B extends A { } // Error: Circular inheritance
Fix: Break the inheritance cycle by removing or restructuring the class hierarchy.
TYHP3007 (Error)BinderTraitConflict. Message: Trait method conflict: .{0}
Two or more traits used by the same class declare methods with the same name, and no conflict resolution (insteadof or as) was provided.
<?tyhp
trait A { public function hello(): void { } }
trait B { public function hello(): void { } }
class MyClass {
use A, B; // Error: Trait method conflict: 'hello'
}
Fix: Use insteadof to resolve the conflict: use A, B { A::hello insteadof B; }.
TYHP3008 (Error)BinderDuplicateUseAlias. Message: Duplicate use alias .{0}
Two use import statements bring in symbols with the same alias name.
<?tyhp
use App\Models\User;
use App\DTOs\User; // Error: Duplicate use alias 'User'
Fix: Use an alias to disambiguate: use App\DTOs\User as UserDTO;.
TYHP3009 (Error)BinderInvalidSelfReference. Message: Invalid .self reference outside of a class
The keyword self was used outside of a class, interface, trait, or enum body.
Fix: Use self only within class-like declarations. Outside of a class, use the fully-qualified class name instead.
TYHP3010 (Error)BinderInvalidParentReference. Message: Invalid .parent reference: class has no parent
The keyword parent was used in a class that does not extend another class.
<?tyhp
class Standalone {
public function test(): void {
parent::test(); // Error: class has no parent
}
}
Fix: Add an extends clause to the class, or remove the parent reference.
TYHP3011 (Error)BinderDuplicateGenericParameter. Message: Duplicate generic type parameter .{0}
A generic class or function declares two type parameters with the same name.
<?tyhp
class Container<T, T> { } // Error: Duplicate generic type parameter 'T'
Fix: Give each generic type parameter a unique name.
TYHP3012 (Error)BinderGenericParameterShadow. Message: Generic type parameter .{0} shadows an existing type
A generic type parameter has the same name as an existing class, interface, or type alias in scope.
Fix: Rename the generic type parameter to avoid shadowing (e.g., use TItem instead of User).
TYHP3013 (Error)BinderMultipleConstructors. Message: Class .{0} declares multiple constructors
A class declares more than one __construct method. PHP and Tyhp only allow a single constructor per class.
Fix: Merge the constructors into a single __construct method with optional parameters, or use static factory methods for alternative construction patterns.
TYHP3014 (Error)ExtensionOperatorMissingTarget. Message: Operator overload in an extension is missing the required .<Type> target
An operator declared inside an extension body must specify the type it extends using the <Type> target syntax.
TYHP3015 (Error)ExtensionOperatorTargetNotAllowed. Message: .<Type> on an operator overload is only allowed inside an extension declaration
The <Type> target on an operator is only valid within an extension declaration, not on a class-member operator.
TYHP3016 (Error)ExtensionOperatorTargetNotFound. Message: The .<Type> target of an extension operator does not resolve to a class or built-in type
The type named as the target of an extension operator overload does not resolve to a known class.
TYHP3017 (Error)BinderUnresolvedExtendsType. Message: Extends type .{0} is not resolved
Run tyhp --explain TYHP3017 for the long-form explanation.
TYHP3018 (Error)BinderUnresolvedImplementsType. Message: Implements type .{0} is not resolved
Run tyhp --explain TYHP3018 for the long-form explanation.
TYHP3019 (Error)BinderUnresolvedReturnType. Message: Return type .{0} is not resolved
Run tyhp --explain TYHP3019 for the long-form explanation.
TYHP3020 (Error)BinderUnresolvedParameterType. Message: Parameter type .{0} is not resolved
Run tyhp --explain TYHP3020 for the long-form explanation.
TYHP3021 (Error)BinderUnresolvedGenericConstraintType. Message: Generic constraint type .{0} is not resolved
Run tyhp --explain TYHP3021 for the long-form explanation.
TYHP3022 (Error)BinderUnresolvedGenericDefaultType. Message: Generic default type .{0} is not resolved
Run tyhp --explain TYHP3022 for the long-form explanation.
TYHP3023 (Error)BinderInvalidExtendsTypeKind. Message: Extends type .{0} is a {1}, not a {2}
Run tyhp --explain TYHP3023 for the long-form explanation.
TYHP3024 (Error)BinderInvalidImplementsTypeKind. Message: Implements type .{0} is a {1}, not an interface
Run tyhp --explain TYHP3024 for the long-form explanation.
Checker errors occur during type checking and semantic analysis.
TYHP4001 (Error)CheckerUnknownError. Message: Unknown checker error: {0}.
A catch-all for unexpected errors during the checking phase.
TYHP4002 (Error)CheckerMultipleVisibilities. Message: .{0} cannot have multiple visibility modifiers
A class member has multiple visibility keywords (public, protected, private).
<?tyhp
class Example {
public protected string $name; // Error: Multiple visibility modifiers
}
Fix: Use only one visibility modifier per declaration.
TYHP4003 (Error)CheckerNotAllowedMemberModifier. Message: Modifier .{0} is not allowed here
A modifier is used in a context where it is not valid.
<?tyhp
interface Cacheable {
static function getCacheKey(): string;
// Error: 'static' is not allowed on interface methods
}
Fix: Remove the disallowed modifier. Check what modifiers are valid for the current context (interface, trait, enum, etc.).
TYHP4004 (Error)CheckerAccessorVisibilityCannotBeMoreVisibleThanProperty. Message: Accessor visibility cannot be more visible than property visibility; .{0} is more visible than {1}
A property hook's (get/set) visibility is more permissive than the property itself.
<?tyhp
class Example {
private string $name {
public get => $this->name; // Error: accessor more visible than property
}
}
Fix: Make the accessor visibility equal to or more restrictive than the property visibility.
TYHP4005 (Error)CheckerMemberModifierConflict. Message: Member modifier .{0} cannot be used at the same time as {1}
Two modifiers on the same declaration are mutually exclusive.
<?tyhp
class Example {
abstract final function process(): void;
// Error: Conflicting modifiers: 'abstract' and 'final'
}
Fix: Remove one of the conflicting modifiers. A method cannot be both abstract and final.
TYHP4006 (Error)CheckerInvalidPropertyAccessorType. Message: Invalid property accessor type .{0}
The property hook type is not recognized (must be get or set).
TYHP4007 (Error)CheckerParameterNotAllowedOnPropertyAccessorType. Message: Parameter declaration is not allowed on property accessor of type .{0}
A get accessor declares a parameter, which is not valid. Only set accessors accept a value parameter.
TYHP4008 (Error)CheckerTypeMismatch. Message: Cannot assign type .{0} to type {1}
The checker reports a type mismatch when a value's type is not assignable to the type its target declares — an assignment, an argument, a return statement, or a property initializer. The first placeholder is the type of the value being supplied; the second is the type the target requires.
<?tyhp
int $count = "hello";
// Error: Cannot assign type 'string' to type 'int'
Make the two types agree: widen or change the declared type, convert the value explicitly, or narrow a nullable or union type with a guard before the assignment.
TYHP4009 (Error)CheckerIncompatibleReturnType. Message: Return type .{0} is not compatible with declared return type {1}
A function or method returns a value whose type does not match its declared return type.
<?tyhp
function getName(): string {
return 42; // Error: Return type 'int' is not compatible with 'string'
}
Fix: Change the return value to match the declared return type, or update the return type declaration.
TYHP4010 (Error)CheckerIncompatibleArgumentType. Message: Argument of type .{0} is not assignable to parameter of type {1}
A function or method call passes an argument whose type does not match the expected parameter type.
<?tyhp
function process(int $id): void { }
process("abc"); // Error: Argument of type 'string' not assignable to 'int'
Fix: Pass a value of the correct type, or cast the argument explicitly.
TYHP4011 (Error)CheckerMissingReturnStatement. Message: Function with return type .{0} must return a value on all code paths
A non-void function has code paths that do not return a value.
<?tyhp
function getStatus(bool $active): string {
if ($active) {
return "active";
}
// Error: not all code paths return a value
}
Fix: Add a return statement for every code path, including else branches and after loops.
TYHP4012 (Warning)CheckerUnreachableCode. Message: Unreachable code detected.
Code exists after a return, throw, break, continue, or exit statement and will never execute.
<?tyhp
function example(): string {
return "done";
echo "this never runs"; // Warning: Unreachable code
}
Fix: Remove the unreachable code or restructure the control flow.
TYHP4013 (Error)CheckerVariableUsedBeforeAssignment. Message: Variable .${0} is used before being assigned
A variable is read before it has been assigned a value on any code path.
<?tyhp
function example(): void {
echo $x; // Error: Variable '$x' is used before being assigned
int $x = 5;
}
Fix: Assign the variable before using it.
TYHP4014 (Error)CheckerVariablePossiblyUndefined. Message: Variable .${0} is possibly undefined
A variable may not be defined on all code paths leading to its use.
<?tyhp
function example(bool $flag): void {
if ($flag) {
string $msg = "yes";
}
echo $msg; // Error: '$msg' is possibly undefined
}
Fix: Initialize the variable before the conditional, or add an else branch that also assigns it.
TYHP4015 (Error)CheckerVariablePossiblyNull. Message: Variable .${0} is possibly null here but is used where a non-null value is required
A variable with a nullable type is used in a context that requires a non-null value without a prior null check.
<?tyhp
function example(?string $name): void {
echo \strlen($name); // Warning: '$name' is possibly null
}
Fix: Add a null check before using the variable, or use the null coalescing operator ??.
TYHP4016 (Error)CheckerVariableTypeRequired. Message: Variable .${0} must have a type annotation or inferable initializer
A variable lacks both an explicit type declaration and an initializer from which the type can be inferred.
<?tyhp
function example(): void {
$x; // Error: must have a type annotation or inferable initializer
}
Fix: Add an explicit type: int $x; or initialize the variable: $x = 0;.
TYHP4017 (Error)CheckerAbstractMethodNotImplemented. Message: Class .{0} does not implement abstract method {1} from {2}
A concrete class extends an abstract class but does not implement all of its abstract methods.
<?tyhp
abstract class Shape {
abstract public function area(): float;
}
class Circle extends Shape {
// Error: does not implement abstract method 'area' from 'Shape'
}
Fix: Implement all abstract methods from the parent class with matching signatures.
TYHP4018 (Error)CheckerInterfaceMethodNotImplemented. Message: Class .{0} does not implement interface method {1} from {2}
A class implements an interface but does not provide implementations for all of its methods.
TYHP4019 (Error)CheckerFinalClassExtended. Message: Cannot extend final class .{0}
A class attempts to extend a class that is declared as final.
<?tyhp
final class Singleton { }
class MySingleton extends Singleton { } // Error: Cannot extend final class
TYHP4020 (Error)CheckerFinalMethodOverridden. Message: Cannot override final method .{0}
A subclass attempts to override a method that is declared as final in the parent class.
TYHP4021 (Error)CheckerReadonlyPropertyReassigned. Message: Cannot assign to readonly property .{0}
A readonly property is being assigned outside of the constructor.
<?tyhp
class User {
public function __construct(
public readonly string $name
): void {}
public function rename(string $newName): void {
$this->name = $newName; // Error: Cannot assign to readonly property
}
}
TYHP4022 (Error)CheckerAbstractClassInstantiated. Message: Cannot instantiate abstract class .{0}
Code attempts to create an instance of an abstract class with new.
TYHP4023 (Error)CheckerEnumCaseTypeMismatch. Message: Enum case value type .{0} does not match backed type {1}
A backed enum case has a value of a type that does not match the enum's backing type.
<?tyhp
enum Status: string {
case Active = 1; // Error: int value for string-backed enum
}
TYHP4024 (Error)CheckerEnumMethodNotAllowed. Message: Enum cannot have a constructor.
An enum declares a method that is not allowed (e.g., a constructor).
TYHP4025 (Error)CheckerMemberNotAccessible. Message: .{0} is {1} and cannot be accessed from {2}
A private or protected member is accessed from outside its allowed scope.
<?tyhp
class Account {
private float $balance = 0.0;
}
Account $a = new Account();
$a->balance; // Error: Cannot access private member 'balance'
TYHP4026 (Error)CheckerBreakOutsideLoop. Message: .break statement is not within a loop or switch
A break statement appears outside of a for, foreach, while, do-while, or switch block.
TYHP4027 (Error)CheckerContinueOutsideLoop. Message: .continue statement is not within a loop
A continue statement appears outside of a loop construct.
TYHP4028 (Error)CheckerAwaitOutsideAsync. Message: .await can only be used inside an async function
The await keyword is used inside a function that is not marked as async.
<?tyhp
function fetchData(): string {
return await getRemoteData(); // Error: await outside of async function
}
Fix: Mark the function as async: async function fetchData(): Promise<string>.
TYHP4029 (Error)CheckerInvalidOperatorForType. Message: Operator .{0} cannot be applied to types {1} and {2}
A binary or unary operator is used with operands whose types do not support that operation.
TYHP4030 (Error)CheckerDisposableRequiresInterface. Message: Disposable assignment .:= requires type implementing IsDisposable
The disposable assignment operator := is used with a type that does not implement the IsDisposable interface.
<?tyhp
class PlainObject { }
$obj := new PlainObject();
// Error: ':=' requires the type to implement IsDisposable
TYHP4031 (Error)CheckerWithKeywordInvalidProperty. Message: Property .{0} does not exist on type {1}
The with keyword references a property name that does not exist on the target type.
TYHP4032 (Error)CheckerTypeGuardInvalidReturn. Message: Type guard function must return .bool
A function with a type guard return type ($param is Type) does not return a boolean value.
TYHP4035 (Error)CheckerGenericConstraintNotSatisfied. Message: Type .{0} does not satisfy constraint {1}
A type argument provided for a generic parameter does not meet the declared constraint.
<?tyhp
class Repository<T extends Entity> { }
// Error: 'string' does not satisfy constraint 'Entity'
Repository<string> $repo = new Repository<string>();
TYHP4036 (Error)CheckerGenericArgumentCountMismatch. Message: Generic type .{0} expects {1} type argument(s), found {2}
The number of generic type arguments does not match the number of generic type parameters declared.
<?tyhp
class Pair<TKey, TValue> { }
Pair<int> $p; // Error: expects 2 type arguments, but 1 was provided
TYHP4037 (Error)CheckerStructPropertyRequired. Message: All struct properties must be typed.
All properties in a struct declaration must have explicit type annotations.
TYHP4038 (Error)CheckerExtensionVisibilityNotAllowed. Message: Visibility adaptation is not allowed on extension members; extensions are always public.
A member inside an extension declaration attempts to adapt or restrict its visibility. Extension members are always public and cannot change visibility.
TYHP4039 (Error)CheckerThrowNotThrowable. Message: .throw expression must be an instance of \Throwable
A throw statement throws a value that does not implement \Throwable.
<?tyhp
throw "something went wrong";
// Error: Cannot throw value of type 'string': must be \Throwable
TYHP4040 (Error)CheckerCatchNotThrowable. Message: Caught type .{0} must implement \Throwable
A catch clause specifies a type that does not implement \Throwable.
TYHP4041 (Error)CheckerCatchNoIntersection. Message: Catch clause cannot use intersection types.
A catch clause uses an intersection type, which is not valid. Use union types (|) instead.
TYHP4042 (Error)CheckerCatchNoScalar. Message: Cannot catch scalar type .{0}
A catch clause specifies a scalar type like int or string.
TYHP4043 (Error)CheckerConditionNotBool. Message: Expected .bool, found {0}
The condition in an if, while, or ternary expression is not a boolean type.
TYHP4044 (Error)CheckerTraitRequirementNotMet. Message: Trait .{0} requires the using class to extend {1}
A trait declares a requirement that the using class must extend a specific base class, but the class does not.
TYHP4045 (Error)CheckerTraitRequirementImplNotMet. Message: Trait .{0} requires the using class to implement {1}
A trait declares a requirement that the using class must implement a specific interface, but the class does not.
TYHP4046 (Error)CheckerAsyncIterableMissingAwait. Message: Cannot iterate .AsyncIterable<{0}> synchronously; use foreach (await $expr as ...) inside an async function
A regular foreach is used on a value that implements AsyncIterable. Async iterables must be iterated with await foreach.
TYHP4047 (Error)CheckerAwaitNonAsyncIterable. Message: .await in foreach requires AsyncIterable<T> or Promise<Iterable<T>>, found {0}
The await foreach construct is used on a type that does not implement AsyncIterable.
TYHP4048 (Error)CheckerVoidInNonReturnPosition. Message: Type .void can only be used as a return type or in generic positions that explicitly allow it via constraint
The void type is used in a position other than a function/method return type, such as a generic type argument or parameter type.
<?tyhp
Collection<void> $items; // Error: 'void' can only be used as a return type
TYHP4049 (Error)CheckerNeverInNonReturnPosition. Message: Type .never can only be used as a return type or in generic positions that explicitly allow it via constraint
The never type is used in a position other than a function/method return type.
TYHP4050 (Error)CheckerUtilityTypeInvalidKey. Message: Key .{0} does not match a property on type {1}
A utility type such as Pick, Omit, or keyof was given a key that is not a known property on the target type.
Fix: Use a key that exists on the type, or adjust the type before selecting keys.
TYHP4051 (Error)CheckerUtilityTypeInvalidArgument. Message: Utility type argument does not satisfy constraint.
A type argument passed to a utility type does not meet that utility's constraints (for example, requiring an object type).
Fix: Pass a type that satisfies the utility's constraints.
TYHP4052 (Warning)CheckerReferenceTypeChanged. Message: Reference parameter .{0} reassigned to type {1}, which differs from declared type {2}
A by-reference parameter was reassigned to a value whose type differs from the parameter's declared type. Callers sharing that reference may observe an unexpected type.
Fix: Keep reference reassignments compatible with the declared parameter type.
TYHP4053 (Error)CheckerDuplicateTypeInComposite. Message: Type .{0} appears more than once in a union or intersection type
The same type appears more than once in a union or intersection (for example int|int or A&A).
Fix: Remove the duplicate member from the composite type.
TYHP4054 (Error)CheckerMixedInComposite. Message: .mixed or never cannot be used in union or intersection types
mixed and never cannot appear as members of a union or intersection because they absorb or contradict the other members.
Fix: Remove mixed/never from the composite, or replace the composite with mixed / never alone when that is the intended type.
TYHP4055 (Error)CheckerRedundantTypeInUnion. Message: Redundant type .{0} in union type
A union member is redundant because a wider member of the same union already covers it, so removing it does not change the set of values. Typical cases are bool|false, object|User, and iterable|array.
This is different from a duplicated member (int|int), which is TYHP4053.
<?tyhp
bool|false $flag;
object|User $entity;
Fix: Remove the redundant member from the union.
TYHP4056 (Error)CheckerUseBoolInsteadOfTrueFalse. Message: Use .bool instead of true|false
The union true|false is exactly the bool type. Spell it as bool instead of listing both boolean literals.
Fix: Replace true|false with bool.
TYHP4057 (Error)CheckerNonClassInIntersection. Message: Non-class type .{0} cannot appear in intersection types
Intersection types (A&B) may only contain class-like members (classes, interfaces, and similar). A non-class type such as a scalar or array cannot appear in an intersection.
Fix: Use a union (|) when mixing scalars with objects, or drop the non-class member.
TYHP4058 (Error)CheckerCallableNotAllowedOnProperty. Message: .callable cannot be used as a property type declaration
A property (including a promoted constructor parameter) cannot be declared with the callable type. PHP does not allow callable on properties.
Fix: Use \Closure, an interface, or a named class type instead of callable.
TYHP4059 (Error)CheckerVoidNotAllowedHere. Message: .void can only be used as a return type
void is only valid as a function or method return type. It cannot be used as a parameter type or property type (see also TYHP4048 for void as a generic type argument).
Fix: Use a different type, or mixed when "no value" is intended.
TYHP4060 (Warning)CheckerVoidRefReturn. Message: Returning by reference from a .void function is deprecated
A function or method declared void uses a by-reference return (function &foo(): void). Returning by reference from a void function is deprecated in PHP.
Fix: Drop the & or give the function a non-void return type.
TYHP4061 (Error)CheckerNeverNotAllowedHere. Message: .never can only be used as a return type
never is only valid as a function or method return type. It cannot be used as a parameter type or property type (see also TYHP4049 for never as a generic type argument).
Fix: Use a different type for parameters and properties.
TYHP4062 (Error)CheckerResourceNotAllowed. Message: .resource cannot be used in user type declarations
resource is a historical PHP runtime type and cannot be written in user type declarations. Tyhp does not accept resource as a parameter, return, property, or alias type.
Fix: Use a class or interface that wraps the resource, or mixed if the value is intentionally untyped.
TYHP4063 (Error)CheckerRefArgMustBeVariable. Message: By-reference argument must be a variable, not a literal or expression.
A by-reference parameter must be passed a variable (or a dereferenceable location such as an array element or object property). Literals and temporary expressions cannot be passed by reference.
Fix: Store the value in a variable and pass that variable.
TYHP4064 (Error)CheckerRelativeTypeOutsideClass. Message: .self or parent used outside class context
self and parent name the enclosing class or its parent. They are not valid outside a class, interface, trait, or enum body (for example in a file-level function).
Fix: Use a named type, or move the declaration into a class-like body.
TYHP4065 (Error)CheckerParentWithoutParent. Message: .parent used in class {0} that has no parent class
parent is used in a class that does not extend another class, so there is no parent type to resolve.
Fix: Add an extends clause, or replace parent with a named type or self.
TYHP4066 (Error)CheckerStaticNotReturnType. Message: .static cannot be used as a parameter or property type
static is a late-binding return type (and is allowed in locals, instanceof, and generic arguments). It cannot be used as a parameter type or a property type.
Fix: Use self, a named class, or a generic parameter instead of static on parameters and properties.
TYHP4067 (Error)CheckerDnfRedundantIntersection. Message: Redundant intersection in DNF type.
A DNF type is a union of intersections, such as (A&B)|(A&C). One of those intersections is redundant because another member already covers it — for example (A&B)|A, where A&B is implied by A.
Fix: Remove the redundant intersection from the DNF type.
TYHP4068 (Error)CheckerNeverMustNotReturn. Message: Function with .never return type must not contain a return statement
Run tyhp --explain TYHP4068 for the long-form explanation.
TYHP4069 (Error)CheckerCannotInstantiateNonClass. Message: Cannot instantiate non-class type .{0}
Run tyhp --explain TYHP4069 for the long-form explanation.
TYHP4070 (Error)CheckerCannotInstantiateTrait. Message: Cannot instantiate trait .{0}
Run tyhp --explain TYHP4070 for the long-form explanation.
TYHP4071 (Error)CheckerCannotInstantiateInterface. Message: Cannot instantiate interface .{0}
Run tyhp --explain TYHP4071 for the long-form explanation.
TYHP4072 (Error)CheckerCannotInstantiateEnum. Message: Cannot instantiate enum .{0}
Run tyhp --explain TYHP4072 for the long-form explanation.
TYHP4073 (Error)CheckerCloneNonObject. Message: .clone cannot be applied to non-object type {0}
Run tyhp --explain TYHP4073 for the long-form explanation.
TYHP4074 (Error)CheckerMagicMethodSignature. Message: Magic method .{0} has invalid signature: {1}
Run tyhp --explain TYHP4074 for the long-form explanation.
TYHP4075 (Error)CheckerDuplicateParameter. Message: Duplicate parameter name .${0}
Run tyhp --explain TYHP4075 for the long-form explanation.
TYHP4076 (Warning)CheckerRequiredAfterOptional. Message: Required parameter .${0} follows optional parameter
Run tyhp --explain TYHP4076 for the long-form explanation.
TYHP4077 (Error)CheckerVariadicNotLast. Message: Variadic parameter must be the last parameter.
Run tyhp --explain TYHP4077 for the long-form explanation.
TYHP4078 (Error)CheckerVariadicWithDefault. Message: Variadic parameter cannot have a default value.
Run tyhp --explain TYHP4078 for the long-form explanation.
TYHP4079 (Error)CheckerDuplicateNamedArgument. Message: Duplicate named argument .{0}
Run tyhp --explain TYHP4079 for the long-form explanation.
TYHP4080 (Error)CheckerPositionalAfterNamed. Message: Positional argument after named argument.
Run tyhp --explain TYHP4080 for the long-form explanation.
TYHP4081 (Error)CheckerUnknownNamedArgument. Message: Named argument .{0} does not match any parameter
Run tyhp --explain TYHP4081 for the long-form explanation.
TYHP4082 (Error)CheckerNamedAfterUnpack. Message: Named argument after argument unpacking.
Run tyhp --explain TYHP4082 for the long-form explanation.
TYHP4083 (Error)CheckerClosureUseUndefined. Message: Variable .${0} in closure use clause is not defined in the enclosing scope
Run tyhp --explain TYHP4083 for the long-form explanation.
TYHP4084 (Warning)CheckerClosureUseThis. Message: .use($this) is redundant in non-static closures
Run tyhp --explain TYHP4084 for the long-form explanation.
TYHP4085 (Error)CheckerStaticClosureThis. Message: Static closure cannot reference .$this
Run tyhp --explain TYHP4085 for the long-form explanation.
TYHP4086 (Error)CheckerYieldOutsideGenerator. Message: .yield can only be used inside a generator function
Run tyhp --explain TYHP4086 for the long-form explanation.
TYHP4087 (Error)CheckerGeneratorInvalidReturnType. Message: Generator function return type must be .Generator, iterable, or Iterator
Run tyhp --explain TYHP4087 for the long-form explanation.
TYHP4088 (Error)CheckerYieldInFinally. Message: .yield inside a finally block is not allowed
Run tyhp --explain TYHP4088 for the long-form explanation.
TYHP4089 (Error)CheckerYieldFromNonIterable. Message: .yield from expression must be iterable or a Generator
Run tyhp --explain TYHP4089 for the long-form explanation.
TYHP4090 (Error)CheckerNonConstantExpression. Message: Non-constant expression in constant-required context.
Run tyhp --explain TYHP4090 for the long-form explanation.
TYHP4091 (Error)CheckerDivisionByZero. Message: Division by zero in constant expression.
Run tyhp --explain TYHP4091 for the long-form explanation.
TYHP4092 (Error)CheckerDuplicateArrayKey. Message: Duplicate array key .{0}
Run tyhp --explain TYHP4092 for the long-form explanation.
TYHP4093 (Error)CheckerInvalidArrayAccess. Message: Cannot use array access on type .{0}
Run tyhp --explain TYHP4093 for the long-form explanation.
TYHP4094 (Error)CheckerDestructuringNonArray. Message: Cannot destructure non-array type .{0}
Run tyhp --explain TYHP4094 for the long-form explanation.
TYHP4095 (Error)CheckerDestructuringSpread. Message: Spread operator in list/destructuring is not allowed.
Run tyhp --explain TYHP4095 for the long-form explanation.
TYHP4096 (Error)CheckerSpreadNonIterable. Message: Spread operator requires an iterable type, found .{0}
Run tyhp --explain TYHP4096 for the long-form explanation.
TYHP4097 (Error)CheckerThisInStaticContext. Message: .$this cannot be used in static context
Run tyhp --explain TYHP4097 for the long-form explanation.
TYHP4098 (Error)CheckerNonStaticCalledStatically. Message: Non-static method .{0} cannot be called statically
Run tyhp --explain TYHP4098 for the long-form explanation.
TYHP4099 (Warning)CheckerStaticCalledOnInstance. Message: Static method .{0} called on instance
Run tyhp --explain TYHP4099 for the long-form explanation.
TYHP4100 (Error)CheckerStaticOutsideClass. Message: .static:: used outside class context
Run tyhp --explain TYHP4100 for the long-form explanation.
TYHP4101 (Error)CheckerSymbolNameNotFound. Message: Symbol .{0} is not found for type {1}
Run tyhp --explain TYHP4101 for the long-form explanation.
TYHP4104 (Error)CheckerGotoProhibited. Message: .goto is prohibited in Tyhp
Run tyhp --explain TYHP4104 for the long-form explanation.
TYHP4105 (Error)CheckerPromotedPropertyNoType. Message: Promoted constructor property must have a type annotation.
Run tyhp --explain TYHP4105 for the long-form explanation.
TYHP4106 (Error)CheckerPromotedPropertyInAbstract. Message: Promoted properties are not allowed in abstract or interface constructors.
Run tyhp --explain TYHP4106 for the long-form explanation.
TYHP4107 (Error)CheckerPromotedVariadic. Message: Variadic parameter cannot be a promoted property.
Run tyhp --explain TYHP4107 for the long-form explanation.
TYHP4108 (Error)CheckerReadonlyClassMutableProperty. Message: Mutable property .{0} in readonly class
Run tyhp --explain TYHP4108 for the long-form explanation.
TYHP4109 (Error)CheckerReadonlyClassStaticProperty. Message: Static property in readonly class.
Run tyhp --explain TYHP4109 for the long-form explanation.
TYHP4110 (Error)CheckerEnumCaseMissingValue. Message: Backed enum case .{0} must have a value
Run tyhp --explain TYHP4110 for the long-form explanation.
TYHP4111 (Error)CheckerEnumCaseValueOnNonBacked. Message: Non-backed enum case .{0} must not have a value
Run tyhp --explain TYHP4111 for the long-form explanation.
TYHP4112 (Error)CheckerEnumCaseDuplicateValue. Message: Duplicate enum case value .{0}
Run tyhp --explain TYHP4112 for the long-form explanation.
TYHP4113 (Error)CheckerEnumPropertyNotAllowed. Message: Enums cannot have instance properties.
Run tyhp --explain TYHP4113 for the long-form explanation.
TYHP4114 (Error)CheckerInterfacePropertyInitializer. Message: Interface property cannot have an initializer.
Run tyhp --explain TYHP4114 for the long-form explanation.
TYHP4115 (Error)CheckerInterfacePropertyNotAllowed. Message: Interfaces cannot have instance property declarations.
Run tyhp --explain TYHP4115 for the long-form explanation.
TYHP4116 (Error)CheckerTraitConflict. Message: Unresolved trait method conflict for .{0}
Run tyhp --explain TYHP4116 for the long-form explanation.
TYHP4117 (Error)CheckerCircularTraitUse. Message: Circular trait use detected: {0}.
Run tyhp --explain TYHP4117 for the long-form explanation.
TYHP4118 (Error)CheckerOverloadSignatureIncompatible. Message: Overload signature is not compatible with implementation signature.
Run tyhp --explain TYHP4118 for the long-form explanation.
TYHP4119 (Warning)CheckerIncomparableTypes. Message: Comparing types .{0} and {1} has no meaningful comparison
Run tyhp --explain TYHP4119 for the long-form explanation.
TYHP4120 (Error)CheckerConcatNonStringable. Message: String concatenation with non-stringable type .{0}
Run tyhp --explain TYHP4120 for the long-form explanation.
TYHP4121 (Warning)CheckerEmptyCatch. Message: Empty .catch block silently swallows exceptions
Run tyhp --explain TYHP4121 for the long-form explanation.
TYHP4122 (Warning)CheckerReturnInFinally. Message: Return statement in a .finally block overwrites the try/catch return value
Run tyhp --explain TYHP4122 for the long-form explanation.
TYHP4123 (Warning)CheckerBreakInFinally. Message: .break/continue in a finally block
Run tyhp --explain TYHP4123 for the long-form explanation.
TYHP4124 (Warning)CheckerDuplicateCatch. Message: Exception type .{0} is already caught by a previous catch clause
Run tyhp --explain TYHP4124 for the long-form explanation.
TYHP4125 (Warning)CheckerCatchOrderBroadFirst. Message: Catching parent exception .{0} before child makes subsequent catch unreachable
Run tyhp --explain TYHP4125 for the long-form explanation.
TYHP4126 (Error)CheckerNotAnAttributeClass. Message: Class .{0} is not declared as an attribute class
Run tyhp --explain TYHP4126 for the long-form explanation.
TYHP4127 (Error)CheckerAttributeTargetMismatch. Message: Attribute .{0} cannot be applied to {1}
Run tyhp --explain TYHP4127 for the long-form explanation.
TYHP4128 (Error)CheckerAttributeNotRepeatable. Message: Attribute .{0} is not repeatable
Run tyhp --explain TYHP4128 for the long-form explanation.
TYHP4129 (Error)CheckerOverrideNotOverriding. Message: Method .{0} has the #[Override] attribute but does not override a parent method
Run tyhp --explain TYHP4129 for the long-form explanation.
TYHP4130 (Warning)CheckerUnusedImport. Message: Unused import .{0}
Run tyhp --explain TYHP4130 for the long-form explanation.
TYHP4131 (Warning)CheckerDuplicateImport. Message: Duplicate import .{0}
Run tyhp --explain TYHP4131 for the long-form explanation.
TYHP4132 (Error)CheckerConflictingImportAlias. Message: Conflicting import alias .{0}
Run tyhp --explain TYHP4132 for the long-form explanation.
TYHP4133 (Error)CheckerVariableVariableProhibited. Message: Variable variables (.$$var) are prohibited in Tyhp
Run tyhp --explain TYHP4133 for the long-form explanation.
TYHP4134 (Error)CheckerDynamicPropertyProhibited. Message: Dynamic property creation is prohibited.
Run tyhp --explain TYHP4134 for the long-form explanation.
TYHP4135 (Error)CheckerCompactProhibited. Message: .compact() is prohibited in Tyhp
Run tyhp --explain TYHP4135 for the long-form explanation.
TYHP4136 (Error)CheckerExtractProhibited. Message: .extract() is prohibited in Tyhp
Run tyhp --explain TYHP4136 for the long-form explanation.
TYHP4137 (Warning)CheckerGlobalVariableWarning. Message: .global $var usage; prefer dependency injection
Run tyhp --explain TYHP4137 for the long-form explanation.
TYHP4138 (Error)CheckerClosureParameterTypeRequired. Message: Cannot infer type for closure parameter .${0}; provide an explicit type annotation
Run tyhp --explain TYHP4138 for the long-form explanation.
TYHP4139 (Error)CheckerCloneWithReadonlyRequiresConfig. Message: Clone .with on readonly property {0} requires build.experimentalReadonlyCloneWith: true in tyhp.json for PHP < 8.5
Run tyhp --explain TYHP4139 for the long-form explanation.
TYHP4140 (Error)CheckerWithReadonlyFinalClass. Message: Cannot use .with on readonly properties of final class {0} on PHP < 8.5
Run tyhp --explain TYHP4140 for the long-form explanation.
TYHP4141 (Error)CheckerWithReadonlyInPlace. Message: Cannot modify readonly property .{0} with in-place with; use clone ... with or new ... with instead
Run tyhp --explain TYHP4141 for the long-form explanation.
TYHP4142 (Error)CheckerMissingArgument. Message: Missing required argument for parameter .${0} of {1}
Run tyhp --explain TYHP4142 for the long-form explanation.
TYHP4143 (Error)CheckerTooManyArguments. Message: Too many arguments passed to .{0}; expected at most {1}, found {2}
Run tyhp --explain TYHP4143 for the long-form explanation.
TYHP4144 (Error)CheckerTemplateStringUnknownEscape. Message: Unknown escape sequence .{0} in template string type
Run tyhp --explain TYHP4144 for the long-form explanation.
TYHP4145 (Error)CheckerTemplateStringInvalidQuantifierRange. Message: Invalid quantifier range .{0} in template string type
Run tyhp --explain TYHP4145 for the long-form explanation.
TYHP4146 (Error)CheckerTemplateStringMaxStatesExceeded. Message: Template string type comparison exceeds the complexity limit ({0} states).
Run tyhp --explain TYHP4146 for the long-form explanation.
TYHP4147 (Error)CheckerExtensionMissingExtends. Message: Extension function .{0} must declare its target type with an extends clause
Run tyhp --explain TYHP4147 for the long-form explanation.
TYHP4148 (Error)CheckerGenericTypeofInStaticContext. Message: .typeof({0}) is not available in a static member because {0} is bound per instance
Run tyhp --explain TYHP4148 for the long-form explanation.
TYHP4150 (Error)CheckerReservedGenericVariantSuffix. Message: .{0} ends with {1}, which is reserved for the generic variant the compiler emits
Run tyhp --explain TYHP4150 for the long-form explanation.
TYHP4151 (Error)CheckerGenericOverrideParameterMismatch. Message: .{0} overrides a generic method and must declare the same generic parameters {1}
Run tyhp --explain TYHP4151 for the long-form explanation.
TYHP4152 (Error)CheckerGenericDefaultInStaticContext. Message: .default({0}) is not available in a static member because {0} is bound per instance
Run tyhp --explain TYHP4152 for the long-form explanation.
TYHP4153 (Error)CheckerConstructorDestructorCannotReturnValue. Message: .{0} cannot return a value
Run tyhp --explain TYHP4153 for the long-form explanation.
TYHP4154 (Error)CheckerPropertyHookInvalidModifier. Message: Cannot use the .{0} modifier on a property hook
Run tyhp --explain TYHP4154 for the long-form explanation.
TYHP4155 (Error)CheckerHookedPropertyReadonly. Message: Hooked properties cannot be readonly.
Run tyhp --explain TYHP4155 for the long-form explanation.
TYHP4156 (Error)CheckerGenericInstanceofInStaticContext. Message: .instanceof {0} / is {0} is not available in a static member because {0} is bound per instance
Run tyhp --explain TYHP4156 for the long-form explanation.
TYHP4157 (Error)CheckerPropertyPossiblyUninitialized. Message: Typed property .${0} is possibly uninitialized here; declare ?T ${0} = null, add an initializer, or guard the read with ?? / isset
PHP throws "Typed property must not be accessed before initialization" when a typed property has no initializer, is not set by constructor property promotion, and has not been definitely assigned on every constructor path before it is read.
Prefer declaring the property as nullable with an explicit null default (?T $prop = null) when the code does not need to distinguish "no value" from "value is null". Otherwise assign it in the constructor on all paths, or guard the read with ?? / isset (which do not throw on uninitialized typed properties).
Assignment via a helper method called from the constructor does not count — only a direct $this->prop = … in the constructor body (or a declaration-level initializer / promoted parameter) is a guaranteed source.
TYHP4158 (Error)CheckerUnsetTypedPropertyWithoutAllowUnset. Message: Cannot .unset typed property ${0} without #[\Tyhp\AllowUnset]; prefer ?T ${0} = null, or add the attribute when distinguishing uninitialized from null is required
PHP's unset() on a typed property returns the slot to the uninitialized state, which defeats property-initialization analysis.
Prefer declaring the property as nullable with an explicit null default (?T $prop = null) when "no value" and null are the same. Only opt in with #[\Tyhp\AllowUnset] when code genuinely needs the uninitialized state; then every unguarded read may report TYHP4157, and unset itself clears definite-initialization within the method.
TYHP4159 (Error)CheckerStructRequiredPropertyNotSet. Message: Required struct property .{0} on {1} must be set via new ... with [...]
Struct properties that are non-nullable and have no default value are required. They cannot be omitted from construction — supply them with new StructName() with [prop => value, ...].
Nullable properties (and properties with defaults) remain optional at construction.
TYHP4160 (Error)CheckerMixedRequiresNarrowing. Message: Type .mixed must be narrowed before this use
mixed is Tyhp's strict top type: any value may be assigned to it, but it cannot be used in type-specific operations until narrowed.
Narrow with a type guard (instanceof / is, \is_string(), \is_int(), a user-defined $param is T guard, or a null check) before member access, calls, indexing, arithmetic, bitwise ops, string concatenation, or similar. Comparison and instanceof/is themselves are allowed so narrowing remains possible.
Assignment and return already reject passing mixed where a more specific type is required (TYHP4008 / TYHP4009 / TYHP4010).
TYHP4161 (Error)CheckerReservedPropertyHookMethodSuffix. Message: .{0} ends with {1}, which is reserved for property-hook polyfill methods the compiler emits
PHP < 8.4 property-hook lowering emits private methods named __get_<prop>__tyhpPropertyHook and __set_<prop>__tyhpPropertyHook, then passes them as first-class callables into PropertyAccessor registration.
A user declaration ending with __tyhpPropertyHook would collide with those generated symbols. Rename the declaration.
TYHP4162 (Error)CheckerPipeRhsNotCallable. Message: Right-hand side of .|> is not callable
The pipe operator (|>) passes the left-hand value as the sole argument to the right-hand callable. The RHS must be a Closure, first-class callable, callable/\Closure-typed value, or an object with __invoke.
Replace the RHS with a single-argument callable (for example strlen(...) or (fn($x) => …)).
TYHP4163 (Error)CheckerPipeRhsInvalidArity. Message: Right-hand side of .|> must accept exactly one argument
The pipe operator (|>) has invalid arity: PHP pipes the left-hand value as a single argument. Callables with more than one required parameter, or with zero parameters, cannot be used on the RHS.
Wrap multi-argument callees in a Closure or arrow function that supplies the extra arguments, e.g. (fn($x) => \str_replace('a', 'b', $x)).
TYHP4164 (Error)CheckerPipeRhsByRefParameter. Message: Right-hand side of .|> must not take parameter ${0} by reference
Piped values are temporaries, so callables whose first parameter is by-reference are rejected (for example \array_pop(...)).
Wrap the call in a Closure that takes the value by value and forwards a local variable by reference if mutation is required.
TYHP4165 (Warning)CheckerNoDiscardReturnUnused. Message: Return value of .{0} is marked #[\NoDiscard] and must be used or discarded with (void)
Functions and methods marked #[\NoDiscard] (PHP 8.5) indicate that ignoring the return value is likely a bug.
Use the return value (assignment, argument, condition, etc.), or cast with (void) to mark an intentional discard: (void)important();.
The ExtCore NoDiscard attribute class is added in Story 21; until then Tyhp still recognizes the attribute name on declarations.
TYHP4166 (Error)CheckerFinalPropertyHookOverridden. Message: Cannot override final property hook .{0}::${1}::{2}()
PHP 8.4 rejects overriding a final property hook at class-declaration time, the same as overriding a final method. final get and final set are independent — only the hook marked final is sealed.
Remove the overriding hook from the child, or drop final from the ancestor hook if the override is intentional.
TYHP4167 (Error)CheckerByRefPropertyGetHookRequiresPhp84. Message: By-ref property hook .&get requires PHP 8.4 or later; target is {0}
PHP 8.4 native property hooks support &get so $ref = &$obj->prop (and array-element writes that rely on by-ref get) can alias backing storage.
When output.phpVersion is below 8.4, Tyhp lowers hooks through magic __get, which cannot return by reference. Emitting an ordinary by-value get would silently change program semantics, so Tyhp reports an error instead.
Raise output.phpVersion to 8.4 or later to keep native &get, or rewrite the property to a by-value get hook if by-ref aliasing is not required.
TYHP4168 (Error)CheckerParameterizedStaticForbidden. Message: Parameterized .static<...> is not allowed; use bare static, self<...>, parent<...>, or an explicit class name
Tyhp forbids parameterized static<...> in every scope, including final classes.
Late-static binding names the late-bound class; it does not invent or rebind generic type arguments. Type arguments come from the call-site class spelling (Child<string>::factory()) or from the receiver/$this instantiation for instance methods.
Use: - bare static for fluent / LSB returns that should follow the late-bound class - self<...> or the declaring class name for factories that stamp method generics onto the class (e.g. _async<T>(...): self<T>) - parent<...> when an explicit parent instantiation is required
final class Promise<TReturn extends void|mixed = void> {
public static function _async<T extends void|mixed>(callable<T> $fn): self<T> { /* ... */ }
public function then<TResult>(callable<TReturn, TResult> $cb): static { /* ... */ }
}
TYHP4200 (Warning)CheckerUnusedVariable. Message: Variable .${0} is assigned but never read
Run tyhp --explain TYHP4200 for the long-form explanation.
TYHP4201 (Warning)CheckerUnusedParameter. Message: Parameter .${0} is never used
Run tyhp --explain TYHP4201 for the long-form explanation.
TYHP4202 (Warning)CheckerUnusedPrivateMember. Message: Private member .{0} is never referenced
Run tyhp --explain TYHP4202 for the long-form explanation.
TYHP4203 (Warning)CheckerAssignmentInCondition. Message: Assignment in condition; use .=== for comparison or add extra parentheses if intentional
Run tyhp --explain TYHP4203 for the long-form explanation.
TYHP4204 (Warning)CheckerConditionAlwaysTrueFalse. Message: Condition is always {0}.
Run tyhp --explain TYHP4204 for the long-form explanation.
TYHP4205 (Warning)CheckerRedundantCast. Message: Redundant cast to .{0}
Run tyhp --explain TYHP4205 for the long-form explanation.
TYHP4206 (Warning)CheckerDeadStore. Message: Value assigned to .${0} is overwritten before being read
Run tyhp --explain TYHP4206 for the long-form explanation.
TYHP4207 (Warning)CheckerUnnecessaryNullCheck. Message: Unnecessary null check on non-nullable type .{0}
Run tyhp --explain TYHP4207 for the long-form explanation.
TYHP4208 (Warning)CheckerUnreachableArm. Message: Unreachable match/switch arm.
Run tyhp --explain TYHP4208 for the long-form explanation.
TYHP4209 (Warning)CheckerLossyCast. Message: Lossy cast from .{0} to {1}
Run tyhp --explain TYHP4209 for the long-form explanation.
TYHP4210 (Info)CheckerErrorThresholdReached. Message: Error threshold reached for this file; further errors are suppressed.
Run tyhp --explain TYHP4210 for the long-form explanation.
TYHP4211 (Warning)CheckerStaticReturnSelfInNonFinal. Message: Returning .new self() from a method with return type static in non-final class {0}; child classes will receive parent instance
Run tyhp --explain TYHP4211 for the long-form explanation.
TYHP4212 (Warning)CheckerDisposableCircularReference. Message: Disposable scope has unresolvable circular references; disposal uses .try/finally instead of DisposableScope
Run tyhp --explain TYHP4212 for the long-form explanation.
TYHP4213 (Error)CheckerExistenceGateInvalidName. Message: Declaration existence gate must check for .{0} (fully-qualified name or __NAMESPACE__.'\Name')
Run tyhp --explain TYHP4213 for the long-form explanation.
TYHP4300 (Error)CheckerPhpVersionInvalidConstraint. Message: Invalid PHP version constraint .{0}
Run tyhp --explain TYHP4300 for the long-form explanation.
TYHP4301 (Error)CheckerPhpVersionDeclareNotAlone. Message: .declare(php=...) must not be combined with other declare directives
Run tyhp --explain TYHP4301 for the long-form explanation.
TYHP4302 (Error)CheckerPhpVersionUnreachable. Message: Unreachable under PHP version constraint .{0}
Run tyhp --explain TYHP4302 for the long-form explanation.
TYHP4303 (Error)CheckerPhpVersionDuplicateDeclaration. Message: Duplicate declaration of .{0} with overlapping PHP version constraints
Run tyhp --explain TYHP4303 for the long-form explanation.
TYHP4304 (Error)CheckerPhpVersionAttributeInvalidTarget. Message: .#[\Tyhp\Php] is not allowed on struct or extension declarations; wrap with declare(php=...) instead
Run tyhp --explain TYHP4304 for the long-form explanation.
TYHP4305 (Error)CheckerPhpVersionAttributeInvalidArgument. Message: .#[\Tyhp\Php] requires a string version argument
Run tyhp --explain TYHP4305 for the long-form explanation.
TYHP4306 (Warning)CheckerPhpVersionDefaulted. Message: .output.phpVersion is unset; defaulting to 8.2
Run tyhp --explain TYHP4306 for the long-form explanation.
TYHP4310 (Error)CheckerGenericDefaultDoesNotSatisfyConstraint. Message: Default type .{0} does not satisfy constraint {1} on generic parameter {2}
Run tyhp --explain TYHP4310 for the long-form explanation.
TYHP4311 (Error)CheckerGenericNonDefaultAfterDefault. Message: Generic parameter .{0} without a default cannot follow parameter {1} which has a default
Run tyhp --explain TYHP4311 for the long-form explanation.
TYHP4312 (Error)CheckerGenericDefaultCircularReference. Message: Generic parameter .{0} has a circular default type reference
Run tyhp --explain TYHP4312 for the long-form explanation.
TYHP4320 (Error)CheckerPropertyPathRequiresInlineFn. Message: Parameter of type .PropertyPath<{0}, {1}> requires an inline fn expression (e.g., fn ($x) => $x->property)
A value that is not an inline fn was passed where PropertyPath<TSource, TReturn> is expected. The compiler reads the property chain out of the arrow function at compile time, so an already-built closure carries no chain it can lower.
<?tyhp
function takes(\Tyhp\PropertyPath<User, string> $path): void {}
takes($someClosure);
Pass an inline arrow function instead — takes(fn ($u) => $u->name). Forwarding an existing PropertyPath value (for example a parameter of the same type) is also accepted.
TYHP4321 (Error)CheckerPropertyPathInvalidBody. Message: PropertyPath expression must be a simple property access chain (e.g., fn ($x) => $x->prop->subProp).
The inline fn body is not a simple property-access chain rooted at the lambda parameter. Method calls, operators, function wrappers, and roots other than the parameter cannot be represented as a property path.
<?tyhp
function takes(\Tyhp\PropertyPath<User, string> $path): void {}
takes(fn ($u) => \strtolower($u->name));
Use only -> or ?-> property accesses starting at the parameter — takes(fn ($u) => $u->address->city).
TYHP4322 (Error)CheckerExpressionUnsupportedNode. Message: Expression trees do not support .{0} expressions; simplify the fn body
The inline fn body contains an expression kind that cannot be represented in an expression tree. Assignments, await, yield, match, instanceof/is, nested fn/closures, free function calls, throw, and similar constructs are rejected so the emitted tree stays a faithful, inspectable data structure.
<?tyhp
function takes(\Tyhp\Expression<User, bool> $pred): void {}
takes(fn ($u) => await $u->load());
Simplify the body to supported forms: property/method access, operators, casts, ternary/??, array access, new, literals, and definitely-assigned captures.
TYHP4323 (Error)CheckerExpressionRequiresInlineFn. Message: Parameter of type .Expression<{0}, {1}> requires an inline fn expression
A value that is not an inline fn was passed where Expression<T, R> is expected. The compiler builds the expression tree from the arrow function at compile time, so an already-built closure carries no tree it can lower.
<?tyhp
function takes(\Tyhp\Expression<User, bool> $pred): void {}
takes($someClosure);
Pass an inline arrow function instead — takes(fn ($u) => $u->age > 18). Forwarding an existing Expression value (for example a parameter of the same type) is also accepted.
TYHP4324 (Error)CheckerExpressionCapturedVarUndefined. Message: Captured variable .${0} in expression tree must be definitely assigned
A variable from the enclosing scope is referenced inside an expression-tree fn, so it becomes a ConstantExpression capture. That variable must be definitely assigned at the construction site; reading an uninitialized local would produce an undefined runtime value in the tree.
<?tyhp
function takes(\Tyhp\Expression<User, bool> $pred): void {}
function demo(): void {
int $minAge;
takes(fn ($u) => $u->age > $minAge);
}
Assign the captured variable before constructing the expression — $minAge = 18; then takes(fn ($u) => $u->age > $minAge).
TYHP4325 (Error)CheckerStructRequiredKeyMissing. Message: Required struct property .{0} is missing from {1}
A required field of a callable-parameter bag (__CallableParametersStruct / __CallableParametersTuple) is missing from the array literal. Parameters without defaults are required struct keys; parameters with defaults are optional keys and may be omitted.
<?tyhp
function apply<TCallable extends callable>(
TCallable $cb,
__CallableParametersStruct<TCallable> $args
): __CallableReturnType<TCallable> {
return $cb();
}
function greet(string $name, int $age = 0): string {
return $name;
}
function demo(): void {
apply(greet(...), ['name' => 'Ada']);
apply(greet(...), []);
}
The first call is valid ($age has a default). The second is not — $name is required. Optionality is modeled as required-key assignability on one struct, not an intersection of every key-subset bag.
TYHP4500 (Warning)CheckerDeprecatedUsage. Message: .{0} is deprecated
Code references a symbol that has been marked as deprecated. The symbol still works but may be removed in a future version.
Fix: Check the deprecation notice for the recommended replacement and migrate your code.
TYHP4501 (Error)CheckerObsoleteUsage. Message: .{0} is obsolete and must not be used
Code references a symbol that has been marked as obsolete. This is stronger than deprecated and the symbol may be removed imminently.
TYHP4800 (Info)CheckerEvalUsage. Message: .eval() usage detected — this is disabled in Tyhp by default
The code uses eval(), which Tyhp disallows by default for security and type-safety reasons.
Fix: Replace eval() with a safer alternative. If eval() is absolutely necessary, enable it with build.allowEval: true in tyhp.json.
TYHP4801 (Error)CheckerIncludeNotAllowed. Message: .include/require is not allowed in Tyhp; use import instead
Tyhp does not allow include, require, include_once, or require_once statements. Use use/import statements and Composer autoloading instead.
TYHP4802 (Error)CheckerNestedNamedFunctionNotAllowed. Message: Named function or method .{0} cannot be declared inside another function or method; nested named declarations are not allowed in Tyhp
Run tyhp --explain TYHP4802 for the long-form explanation.
Emitter errors occur during PHP code generation.
TYHP5001 (Error)EmitterUnknownError. Message: Unknown emitter error: {0}.
A catch-all for unexpected errors during PHP code generation.
TYHP5002 (Error)EmitterUnsupportedAstNode. Message: Cannot emit AST node type .{0} — no emission handler implemented
The emitter encountered an AST node type that it does not know how to convert to PHP. This typically indicates a new language feature whose emitter support is not yet complete.
TYHP5003 (Error)EmitterOutputPathConflict. Message: Output path conflict: .{0} is targeted by multiple declarations
Two or more class/file declarations would produce output at the same file path.
Fix: Ensure each class has a unique fully-qualified name. If two classes share a name, place them in different namespaces.
TYHP5004 (Error)EmitterNamespaceMismatch. Message: Cannot merge output files: namespace mismatch (.{0} vs {1})
An attempt to merge two output files failed because they declare different namespaces.
TYHP5005 (Error)EmitterInvalidOutputPath. Message: Invalid output path: .{0} — {1}
The computed output path for a generated PHP file is invalid or inaccessible.
TYHP5006 (Warning)EmitterTypeErasureWarning. Message: Type .{0} is erased to mixed in PHP output
A Tyhp type could not be represented in PHP and was erased to mixed. This is informational -- the type checking was still performed at compile time.
TYHP5007 (Error)EmitterWriteError. Message: Failed to write output file .{0}: {1}
The emitter could not write a generated PHP file to disk due to a file system error.
TYHP5008 (Warning)EmitterTyhpConstructNotImplemented. Message: Tyhp construct .{0} is not yet supported by the emitter
A Tyhp-specific language feature does not yet have emitter support. The code compiles but the feature is not emitted.
TYHP5009 (Error)EmitterInvalidDeclareDirective. Message: Invalid declare directive: {0}.
A declare() statement contains an invalid or conflicting directive.
TYHP5010 (Warning)EmitterEmptyOutputFile. Message: Output file .{0} has no statements and will not be written
An output file was generated with no PHP statements (e.g., a source file contained only type aliases or struct declarations that are erased).
TYHP5011 (Warning)EmitterMergeConflict. Message: Conflicting declarations during merge of .{0}: {1}
Two output files being merged into one contain conflicting declarations.
TYHP5012 (Error)EmitterUnsupportedConstruct. Message: Tyhp construct .{0} cannot be emitted to PHP
An unsupported Tyhp construct cannot be lowered to PHP — it is not merely unimplemented yet (that is TYHP5008). The emitter has no valid PHP representation for the named construct.
Fix: Rewrite the code using a construct Tyhp can emit, or check whether a newer compiler adds support.
TYHP5013 (Error)EmitterNameConflict. Message: Generated method name .{0} conflicts with an existing method in {1}
A method name the emitter generated (for example a lowered hook, generic variant, or helper) conflicts with a method that already exists on the same class.
Fix: Rename the authored method so it does not clash with the generated name.
TYHP5014 (Error)EmitterMissingRuntime. Message: TyhpLib runtime is required but not configured for .{0}
The compiled output needs the TyhpLib runtime (the tyhp/core family of packages) for the named construct, but the project is not configured to include it.
Fix: Restore the runtime package reference (Composer tyhp/core / tyhp.json runtime settings) and rebuild.
TYHP5015 (Error)EmitterStructBackingError. Message: Configured struct backing class .{0} is not found
Run tyhp --explain TYHP5015 for the long-form explanation.
TYHP5016 (Error)EmitterDisposableError. Message: Disposable variable of type .{0} does not implement IsDisposable
Run tyhp --explain TYHP5016 for the long-form explanation.
TYHP5017 (Warning)EmitterAttributeStrippedForPhpVersion. Message: Attribute .{0} on {1} is stripped; target PHP {2} cannot represent it
PHP only allows attributes on certain constructs starting at specific versions. Top-level (non-class) const attributes require PHP 8.5+. Attributes on property hooks require native property hooks (PHP 8.4+); when hooks are lowered for an older output.phpVersion, those attributes cannot be preserved in a Reflection-compatible form.
Raise output.phpVersion, or remove the attribute if it is not needed at runtime.
TYHP5018 (Error)EmitterInteropContractMismatch. Message: Runtime package .{0} interop contract version is {1}, expected {2}
Compiled Tyhp depends on concrete \Tyhp\* runtime shapes. Each runtime Composer package stamps extra.tyhp.interopContractVersion, which must match the compiler's InteropContract.CurrentVersion.
Upgrade or reinstall matching tyhp/core, tyhp/async, tyhp/decimal, and/or tyhp/lambda packages, or upgrade the Tyhp compiler so both sides share the same contract version. See the interop contract docs.
TYHP5019 (Error)EmitterPostfixOperatorOverloadRequiresStatementSplit. Message: Overloaded postfix .{0} cannot be statement-split in this expression; capture the prior value in a separate statement
Overloaded ++ / -- rewrites to a method call plus write-back. Postfix forms must yield the value from before that write-back, which the emitter does by splitting into preceding statements ($__old = $a; $a = Type::__increment($a); … $__old).
That split is not safe inside short-circuit operands (&&, ||, ??), ternary arms, else if conditions (reached only when earlier conditions in the chain were false), or loop conditions that re-evaluate each iteration. Move the postfix into its own statement (or use prefix ++$a when the new value is intended), then use the captured variable in the expression.
Configuration errors are reported when tyhp.json or CLI options are invalid.
TYHP6001 (Error)ConfigUnknownError. Message: Configuration error.
A generic configuration error that does not match a more specific code.
TYHP6002 (Error)ConfigMissingRequiredField. Message: Required configuration field is missing.
A required field in tyhp.json is not present.
TYHP6003 (Warning)ConfigInvalidValue. Message: Invalid configuration value for .{0}: {1}
A configuration value is out of range, the wrong type, or otherwise invalid.
TYHP6004 (Error)ConfigInvalidGlobPattern. Message: Invalid glob pattern in configuration.
An include or exclude glob pattern in tyhp.json is malformed.
TYHP6005 (Error)ConfigOutputPathNotWritable. Message: Output path is not writable.
The configured output directory does not exist and cannot be created, or the process does not have write permissions.
TYHP6006 (Warning)ConfigInvalidPhpVersion. Message: Unsupported PHP version .{0}; using default 8.4
The output.phpVersion configuration specifies a PHP version that is not recognized or supported.
TYHP6007 (Error)ConfigPsr4InvalidMapping. Message: Invalid PSR-4 mapping in configuration.
A psr4 configuration entry maps a namespace to a path that is invalid or does not exist.
TYHP6008 (Warning)ConfigInvalidProjectType. Message: Unrecognized project type .{0}; using application
Run tyhp --explain TYHP6008 for the long-form explanation.
CLI errors are reported by compiler actions (build, lint, init, and related commands).
TYHP7100 (Error)BuildUnknownError. Message: Build failed.
A generic build action error.
TYHP7101 (Info)BuildNoSourceFiles. Message: No source files found matching include patterns.
The build action found no .tyhp or .php files matching the configured include patterns.
Fix: Check the include and exclude patterns in tyhp.json. Ensure your source files have the correct file extensions.
TYHP7102 (Error)BuildOutputPathConflict. Message: Output path conflict: multiple files write to .{0}
During the build, multiple output file declarations would write to the same output path on disk.
TYHP7103 (Error)BuildFileWriteError. Message: Failed to write output file .{0}: {1}
A generated PHP file could not be written to disk (write failed: disk full, permission denied, or similar).
TYHP7104 (Error)BuildCleanFailed. Message: Cannot clean output directory .{0}: {1}
The --clean flag was used but the output directory could not be cleaned (e.g., safety check failed or permission denied).
TYHP7105 (Warning)BuildRuntimePackageNotAvailable. Message: Tyhp runtime Composer package .{0} is not available; compiled code may not run correctly without it
A Tyhp runtime Composer package (e.g., tyhp/core, tyhp/decimal, tyhp/async) is needed by the compiled output but could not be found or installed.
TYHP7200 (Error)LintFileNotFound. Message: File not found: .{0}
The --file argument to tyhp lint specifies a file path that does not exist.
TYHP7201 (Error)LintPathNotFound. Message: Path .{0} does not exist
A positional path passed to tyhp lint does not exist on disk.
TYHP7202 (Error)LintInvalidPath. Message: Path .{0} is invalid: {1}
A positional path passed to tyhp lint could not be interpreted as a file or directory.
TYHP7203 (Error)LintAccessDenied. Message: Access denied: {0}.
Access was denied while reading a source file or directory during lint (permissions, sandbox, or similar).
TYHP7204 (Error)LintIoError. Message: I/O error: {0}.
An I/O failure occurred while discovering or reading source files.
TYHP7205 (Error)LintUnexpectedError. Message: Unexpected error ({0}): {1}.
An unexpected failure occurred during linting; the first placeholder identifies the failure category.
TYHP7206 (Warning, Info)LintNoSourceFiles. Message: No source files match the include/exclude paths in .tyhp.json
No source files matched. Reported as informational for an empty project include set, and as a warning when explicit paths resolve to nothing.
TYHP7207 (Error)LintCancelled. Message: Lint cancelled.
Linting was cancelled (for example Ctrl+C). Diagnostics collected up to that point are still reported.
TYHP7208 (Error)LintFileNotInProject. Message: File .{0} is not within the project source paths
The file specified with --file is not part of the configured project source paths.
TYHP7209 (Info)LintFixApplied. Message: Auto-fix applied: {0}.
An auto-fix was successfully applied to resolve a lint issue (when using tyhp lint --fix).
TYHP7210 (Warning)LintFixFailed. Message: Auto-fix .{0} could not be applied: {1}
An auto-fix was attempted but could not be applied. The placeholders name the fix and the reason (auto-fix implementations are still stubs, so this currently reports Not yet implemented).
TYHP7211 (Error)LintUnsupportedFormat. Message: Unsupported output format .{0}; valid formats: text, json, sarif
The --format argument to tyhp lint specifies a format that is not recognized.
TYHP7505 (Error)TyhpdefLibraryEntrypointDetected. Message: Library projects cannot contain entrypoint files with executable top-level code: .{0}
Run tyhp --explain TYHP7505 for the long-form explanation.
TYHP7800 (Error)IntegrityCheckConfigInvalid. Message: Integrity check failed: project configuration is invalid.
Run tyhp --explain TYHP7800 for the long-form explanation.
TYHP7801 (Error)IntegrityCheckTyhpdefError. Message: Integrity check failed: one or more tyhpdef files could not be parsed.
Run tyhp --explain TYHP7801 for the long-form explanation.
TYHP7802 (Error)IntegrityCheckCacheCorrupted. Message: Integrity check failed: AST cache entries are corrupted or unreadable.
Run tyhp --explain TYHP7802 for the long-form explanation.
TYHP7803 (Error)IntegrityCheckEnvironmentError. Message: Integrity check failed: runtime environment problem detected.
Run tyhp --explain TYHP7803 for the long-form explanation.
Tyhpdef errors are reported when loading or validating type-definition files.
TYHP8001 (Error)TyhpdefParseError. Message: Failed to parse tyhpdef file: {0}.
A .tyhpdef file contains syntax errors and could not be parsed.
Fix: Check the tyhpdef file for syntax errors. Tyhpdef syntax is similar to Tyhp but only supports declarations (no function bodies).
TYHP8002 (Error)TyhpdefDuplicateDeclaration. Message: Tyhpdef declares symbol .{0} which already exists
A tyhpdef file declares a symbol (class, function, constant) that is already declared by another tyhpdef or by the project's source code.
TYHP8003 (Error)TyhpdefFileNotFound. Message: Configured tyhpdef path .{0} does not exist
A tyhpdef file path specified in tyhp.json or via CLI arguments does not exist on disk.
TYHP8004 (Error)TyhpdefInvalidFormat. Message: Tyhpdef file .{0} has an unexpected structure
A tyhpdef file was parsed but its structure or format does not match what the compiler expects (e.g., missing required sections, invalid nesting).
TYHP8005 (Error)TyhpdefBindError. Message: Tyhpdef bind error: {0}.
A .tyhpdef file parsed, but binding it into the symbol table failed. The placeholder is the underlying bind exception text.
This is a semantic bind failure, not a parse error (TYHP8001).
Fix: Check the tyhpdef for unresolved names, illegal members, or other bind-time problems named in the message.
TYHP8010 (Error)TyhpdefExtensionConflict. Message: Extension member .{0} conflicts with a declared member on class {1}
A tyhpdef inline extension declares a member that collides with a member already declared on the same class.
TYHP8011 (Error)TyhpdefExtensionNotFound. Message: A .use extension reference in tyhpdef does not resolve to {0}
A use extension reference inside a tyhpdef file points to an extension that does not exist.
TYHP8012 (Error)TyhpdefInlineExtensionInvalidMember. Message: Invalid member with the .extension qualifier in tyhpdef
A member marked with the extension qualifier inside a tyhpdef declaration is not a valid extension member.
TYHP8013 (Error)TyhpdefExtensionOperatorRequiresBody. Message: .extension operator {0} requires a body; use bodyless operator {0}(…); (without extension) for native PHP operators
Run tyhp --explain TYHP8013 for the long-form explanation.
TYHP8025 (Error)TyhpdefDuplicateFqnAcrossPackages. Message: Fully-qualified name .{0} is defined in packages {1} and {2}
Run tyhp --explain TYHP8025 for the long-form explanation.
TYHP8026 (Warning)TyhpdefPhpExtensionPackageNotFound. Message: PHP extension package not found; install .tyhp/php via Composer for full PHP built-in type checking
Run tyhp --explain TYHP8026 for the long-form explanation.
TYHP8027 (Warning)TyhpdefRuntimePackageNotFound. Message: Runtime package not found for .tyhp/{0}; install the package via Composer for full type checking
Run tyhp --explain TYHP8027 for the long-form explanation.