psalm-plugin-laravel icon indicating copy to clipboard operation
psalm-plugin-laravel copied to clipboard

Undefined array key "factory" with Laravel 11

Open mzur opened this issue 1 year ago • 7 comments

Describe the bug I installed a fresh setup of Laravel 11 (PHP 8.2) with composer create-project laravel/laravel example-app. Then I downgraded PHPUnit (because of #384) with composer require --dev -W phpunit/phpunit:^10 and installed Psalm with composer require --dev -W psalm/plugin-laravel. Next I run steps 2-4 of the quickstart instructions.

I get the following error:

Target PHP version: 8.2 (inferred from composer.json).
Scanning files...
Analyzing files...

░░
   Exception 

  ErrorException Undefined array key "factory"
Emitted in /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/StaticPropertyFetchAnalyzer.php:299
Stack trace in the forked worker:
#0 /home/m/Desktop/example-app/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(256): Illuminate\Foundation\Bootstrap\HandleExceptions->handleError()
#1 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/StaticPropertyFetchAnalyzer.php(299): Illuminate\Foundation\Bootstrap\HandleExceptions->Illuminate\Foundation\Bootstrap\{closure}()
#2 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(278): Psalm\Internal\Analyzer\Statements\Expression\Fetch\StaticPropertyFetchAnalyzer::analyze()
#3 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(90): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::handleExpression()
#4 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/IssetAnalyzer.php(60): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::analyze()
#5 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/IssetAnalyzer.php(47): Psalm\Internal\Analyzer\Statements\Expression\IssetAnalyzer::analyzeIssetVar()
#6 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(258): Psalm\Internal\Analyzer\Statements\Expression\IssetAnalyzer::analyze()
#7 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(90): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::handleExpression()
#8 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Block/IfConditionalAnalyzer.php(116): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::analyze()
#9 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Block/IfElseAnalyzer.php(98): Psalm\Internal\Analyzer\Statements\Block\IfConditionalAnalyzer::analyze()
#10 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php(517): Psalm\Internal\Analyzer\Statements\Block\IfElseAnalyzer::analyze()
#11 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php(197): Psalm\Internal\Analyzer\StatementsAnalyzer::analyzeStatement()
#12 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php(511): Psalm\Internal\Analyzer\StatementsAnalyzer->analyze()
#13 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ClassAnalyzer.php(1859): Psalm\Internal\Analyzer\FunctionLikeAnalyzer->analyze()
#14 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ClassAnalyzer.php(1533): Psalm\Internal\Analyzer\ClassAnalyzer->analyzeClassMethod()
#15 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ClassAnalyzer.php(459): Psalm\Internal\Analyzer\ClassAnalyzer->analyzeTraitUse()
#16 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FileAnalyzer.php(201): Psalm\Internal\Analyzer\ClassAnalyzer->analyze()
#17 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(1587): Psalm\Internal\Analyzer\FileAnalyzer->analyze()
#18 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Fork/Pool.php(189): Psalm\Internal\Codebase\Analyzer->analysisWorker()
#19 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(372): Psalm\Internal\Fork\Pool->__construct()
#20 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(272): Psalm\Internal\Codebase\Analyzer->doAnalysis()
#21 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php(538): Psalm\Internal\Codebase\Analyzer->analyzeFiles()
#22 /home/m/Desktop/example-app/vendor/vimeo/psalm/src/Psalm/Internal/Cli/Psalm.php(379): Psalm\Internal\Analyzer\ProjectAnalyzer->check()
#23 /home/m/Desktop/example-app/vendor/vimeo/psalm/psalm(9): Psalm\Internal\Cli\Psalm::run()
#24 /home/m/Desktop/example-app/vendor/bin/psalm(119): include('...')
#25 {main}

  at vendor/vimeo/psalm/src/Psalm/Internal/Fork/Pool.php:383
    379▕                                 ($this->task_done_closure)($message->data);
    380▕                             }
    381▕                         } elseif ($message instanceof ForkProcessErrorMessage) {
    382▕                             $this->killAllChildren();
  ➜ 383▕                             throw new Exception($message->message);
    384▕                         } else {
    385▕                             $this->killAllChildren();
    386▕                             throw new Exception('Child should return ForkMessage - response type=' . gettype($message));
    387▕                         }

Impacted Versions

barryvdh/laravel-ide-helper           3.1.0   Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.
laravel/framework                     11.16.0 The Laravel Framework.
laravel/pint                          1.16.2  An opinionated code formatter for PHP.
laravel/prompts                       0.1.24  Add beautiful and user-friendly forms to your command-line applications.
laravel/sail                          1.30.2  Docker files for running a basic Laravel application.
laravel/serializable-closure          1.3.3   Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.
laravel/tinker                        2.9.0   Powerful REPL for the Laravel framework.
psalm/plugin-laravel                  2.11.0  Psalm plugin for Laravel
vimeo/psalm                           5.25.0  A static analysis tool for finding errors in PHP applications

Additional context This seems related to the HasFactory trait of the default User model. Any hints where else I could look?

mzur avatar Jul 17 '24 08:07 mzur

Same here @mzur

tm1000 avatar Aug 16 '24 17:08 tm1000

SAme here. Any updates on this?

CodeWithKyrian avatar Sep 08 '24 09:09 CodeWithKyrian

the same error

sergey-yabloncev avatar Sep 11 '24 14:09 sergey-yabloncev

This appears to have been caused by the changed generics in https://github.com/laravel/framework/pull/52005. Applying the changes described there solved the issue for us.

JeftavanderHorst avatar Sep 12 '24 09:09 JeftavanderHorst

@JeftavanderHorst adding /** @use HasFactory<UserFactory> */?

tm1000 avatar Sep 12 '24 19:09 tm1000

@JeftavanderHorst adding /** @use HasFactory<UserFactory> */?

i added the use comment and the attribute

/** @use HasFactory<UserFactory> */ use HasFactory;

protected static string $factory = UserFactory::class;

Nicolas-Her avatar Sep 19 '24 08:09 Nicolas-Her

same error

Lukasss93 avatar Oct 07 '24 22:10 Lukasss93

Same here with a brand new model created by artisan

php artisan make:model Moose

Creates:

<?php                                                                                               
                                                                                                    
namespace App\Models;                                                                               
                                                                                                    
use Illuminate\Database\Eloquent\Factories\HasFactory;                                              
use Illuminate\Database\Eloquent\Model;                                                             
                                                                                                    
class Moose extends Model                                                                           
{                                                                                                   
    use HasFactory;                                                                                                                                                                                      
}              

Without any changes it throws

   ErrorException 

  Undefined array key "factory"

  at vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/StaticPropertyFetchAnalyzer.php:299
    295▕             $statements_analyzer,
    296▕         );
    297▕ 
    298▕         $class_storage = $codebase->classlike_storage_provider->get($declaring_property_class);
  ➜ 299▕         $property = $class_storage->properties[$prop_name];
    300▕ 
    301▕         if (!$property->is_static) {
    302▕             if ($context->inside_isset) {
    303▕                 return true;

rwkymapcreator avatar Oct 30 '24 16:10 rwkymapcreator

Also encountering this issue

juliangums avatar Nov 27 '24 15:11 juliangums

Should be fixed within:

Fixed by PR: https://github.com/psalm/psalm-plugin-laravel/pull/389

alies-dev avatar Feb 16 '25 16:02 alies-dev