Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uncaught Exception: InvalidArgumentException Could not get class storage for class-string-map #8626

Closed
yunosh opened this issue Oct 27, 2022 · 10 comments

Comments

@yunosh
Copy link

yunosh commented Oct 27, 2022

Emitted in /Users/janschneider/.composer/vendor/vimeo/psalm/src/Psalm/Internal/Provider/ClassLikeStorageProvider.php:45

This is a strange class name it is looking for, obviously not from my code base.
Running psalm with --debug-by-line reveals that it stops at line 111 of a compiled Symfony container:

110:        $this->privates['service_container'] = function () {
111:            include_once \dirname(__DIR__, 4).'/vendor/league/openapi-psr7-validator/src/PSR7/ValidatorBuilder.php';
112:            include_once \dirname(__DIR__, 4).'/src/EventListener/RequestLanguageListener.php';
@psalm-github-bot
Copy link

Hey @yunosh, can you reproduce the issue on https://psalm.dev ?

@orklah
Copy link
Collaborator

orklah commented Oct 27, 2022

class-string-map is a Psalm's pseudo type that describe an array which has class-string offsets and for each offset, contains an instance of that class-string.

I'm not sure why Psalm would fail to recognize it though. Do you have the latest Psalm version? Do you know what /src/EventListener/RequestLanguageListener.php contains?

@yunosh
Copy link
Author

yunosh commented Oct 28, 2022

Yes, this is both with Psalm 4.15.0 (locally) as with the latest 4.29.0 (inside Docker container). RequestLanguageListener ist harmless:

<?php
declare(strict_types = 1);

namespace XXX\EventListener;

use Symfony\Component\HttpKernel\Event\RequestEvent;

final class RequestLanguageListener
{

    public function onKernelRequest(RequestEvent $event): void
    {
        if (!$event->isMainRequest()) {
            return;
        }

        $request = $event->getRequest();
        $request->setLocale($request->headers->get('Accept-Language', 'de-DE'));
    }

}

@weirdan
Copy link
Collaborator

weirdan commented Nov 10, 2022

class-string-map is likely something used (or inferred) in the container, as it will likely contain a map of class/interface names to instances of those classes/interfaces. Can you upload your compiled container somewhere for us to see?

@yunosh
Copy link
Author

yunosh commented Nov 18, 2022

If you are talking about the Symfony container of the app that's being analyzed, this won't help, because the error even occurs if there is no container at all.
Or do you mean the container of Psalm (does it have one?)? That's running off a separate Docker instance.

@weirdan
Copy link
Collaborator

weirdan commented Nov 19, 2022

I mean the DI container used by Symfony.

Also, it would be useful to see the backtrace for this exception.

@yunosh
Copy link
Author

yunosh commented Nov 25, 2022

Yes, I figured that you might talk about the Symfony container, but I still don't know which Symfony container, please see my last question. Or maybe I need to tell you more about the setup. Psalm is executed, along other checks, within a Docker container, running CaptainHook as a pre-commit hook.
This is the backtrace:

Uncaught InvalidArgumentException: Could not get class storage for class-string-map in /pre-commit/vendor/vimeo/psalm/src/Psalm/Internal/Provider/ClassLikeStorageProvider.php:46
Stack trace:
#0 /pre-commit/vendor/vimeo/psalm/src/Psalm/Internal/TypeVisitor/TypeChecker.php(364): Psalm\Internal\Provider\ClassLikeStorageProvider->get('class-string-ma...')
#1 /pre-commit/vendor/vimeo/psalm/src/Psalm/Internal/TypeVisitor/TypeChecker.php(125): Psalm\Internal\TypeVisitor\TypeChecker->checkTemplateParam(Object(Psalm\Type\Atomic\TTemplateParam))
#2 /pre-commit/vendor/vimeo/psalm/src/Psalm/Type/NodeVisitor.php(20): Psalm\Internal\TypeVisitor\TypeChecker->enterNode(Object(Psalm\Type\Atomic\TTemplateParam))
#3 /pre-commit/vendor/vimeo/psalm/src/Psalm/Type/NodeVisitor.php(31): Psalm\Type\NodeVisitor->traverse(Object(Psalm\Type\Atomic\TTemplateParam))
#4 /pre-commit/vendor/vimeo/psalm/src/Psalm/Type/NodeVisitor.php(31): Psalm\Type\NodeVisitor->traverse(Object(Psalm\Type\Union))
#5 /pre-commit/vendor/vimeo/psalm/src/Psalm/Type/NodeVisitor.php(31): Psalm\Type\NodeVisitor->traverse(Object(Psalm\Type\Atomic\TGenericObject))
#6 /pre-commit/vendor/vimeo/psalm/src/Psalm/Type/NodeVisitor.php(31): Psalm\Type\NodeVisitor->traverse(Object(Psalm\Type\Union))
#7 /pre-commit/vendor/vimeo/psalm/src/Psalm/Type/NodeVisitor.php(45): Psalm\Type\NodeVisitor->traverse(Object(Psalm\Type\Atomic\TClassStringMap))
#8 /pre-commit/vendor/vimeo/psalm/src/Psalm/Type/Union.php(1449): Psalm\Type\NodeVisitor->traverseArray(Array)
#9 /pre-commit/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeAnalyzer.php(844): Psalm\Type\Union->check(Object(Psalm\Internal\Analyzer\MethodAnalyzer), Object(Psalm\CodeLocation\DocblockTypeLocation), Array, Array, false, false)
#10 /pre-commit/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php(417): Psalm\Internal\Analyzer\FunctionLike\ReturnTypeAnalyzer::checkReturnType(Object(PhpParser\Node\Stmt\ClassMethod), Object(Psalm\Internal\Analyzer\ProjectAnalyzer), Object(Psalm\Internal\Analyzer\MethodAnalyzer), Object(Psalm\Storage\MethodStorage), Object(Psalm\Context))
#11 /pre-commit/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ClassAnalyzer.php(1798): Psalm\Internal\Analyzer\FunctionLikeAnalyzer->analyze(Object(Psalm\Context), Object(Psalm\Internal\Provider\NodeDataProvider), Object(Psalm\Context))
#12 /pre-commit/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ClassAnalyzer.php(425): Psalm\Internal\Analyzer\ClassAnalyzer->analyzeClassMethod(Object(PhpParser\Node\Stmt\ClassMethod), Object(Psalm\Storage\ClassLikeStorage), Object(Psalm\Internal\Analyzer\ClassAnalyzer), Object(Psalm\Context), Object(Psalm\Context))
#13 /pre-commit/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FileAnalyzer.php(229): Psalm\Internal\Analyzer\ClassAnalyzer->analyze(Object(Psalm\Context), Object(Psalm\Context))
#14 /pre-commit/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(362): Psalm\Internal\Analyzer\FileAnalyzer->analyze()
#15 /pre-commit/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(619): Psalm\Internal\Codebase\Analyzer->Psalm\Internal\Codebase\{closure}(2892, '/app/design-sui...')
#16 /pre-commit/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(291): Psalm\Internal\Codebase\Analyzer->doAnalysis(Object(Psalm\Internal\Analyzer\ProjectAnalyzer), 1)
#17 /pre-commit/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php(1210): Psalm\Internal\Codebase\Analyzer->analyzeFiles(Object(Psalm\Internal\Analyzer\ProjectAnalyzer), 1, false, false)
#18 /pre-commit/vendor/vimeo/psalm/src/Psalm/Internal/Cli/Psalm.php(375): Psalm\Internal\Analyzer\ProjectAnalyzer->checkPaths(Array)
#19 /pre-commit/vendor/vimeo/psalm/psalm(7): Psalm\Internal\Cli\Psalm::run(Array)
#20 /pre-commit/vendor/bin/psalm(120): include('/pre-commit/ven...')
#21 {main}
(Psalm 4.29.0@7ec5ffbd5f68ae03782d7fd33fff0c45a69f95b3 crashed due to an uncaught Throwable)

@weirdan
Copy link
Collaborator

weirdan commented Nov 25, 2022

this won't help, because the error even occurs if there is no container at all.

Can you clarify what you mean by 'no container at all'?

@yunosh
Copy link
Author

yunosh commented Nov 27, 2022

No Symfony DI container inside the Symfony application, i.e. if you run Psalm on the Symfony application's directory without it having warmed up the cache, and thus without having generated the container.

@ptomulik
Copy link
Contributor

I've seen something similar in #9401

@ptomulik ptomulik mentioned this issue Feb 26, 2023
@orklah orklah closed this as completed Feb 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants