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

PHPStan Pro "not a valid ini size" error when using PHPSTAN_PRO_WEB_PORT env var #5433

Closed
angrybrad opened this issue Aug 3, 2021 · 20 comments
Labels

Comments

@angrybrad
Copy link

Bug report

Running 0.12.94 of PHPStan and trying out the Pro version.

Using Nitro, which is a Docker-based development environment. That container already exposes port 3000, so I figured I'd be able to tell PHPStan to use that with PHPSTAN_PRO_WEB_PORT.

But I'm getting the following error, which seems like it could be an error not related to Docker at all.

nitro@cms-3:/app$ PHPSTAN_PRO_WEB_PORT=3000 ./vendor/bin/phpstan analyze --verbose --pro
Note: Using configuration file /app/phpstan.neon.
 1168/1168 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100% 24 secs

Used memory: 183.28 MB
Running in Docker? Don't forget to do these steps:
1) Publish this port when running Docker:
   -p 127.0.0.1:3000:3000
2) Map the temp directory to a persistent volume
   so that you don't have to log in every time:
   -v ~/.phpstan-pro:/tmp/phpstan-fixer

PHP Fatal error:  Uncaught InvalidArgumentException:  is not a valid ini size in phar:///tmp/phpstan-fixer/phpstan-fixer.phar/vendor/react/http/src/Io/IniUtil.php:26
Stack trace:
#0 phar:///tmp/phpstan-fixer/phpstan-fixer.phar/vendor/react/http/src/Server.php(333): React\Http\Io\IniUtil::iniSizeToBytes()
#1 phar:///tmp/phpstan-fixer/phpstan-fixer.phar/vendor/react/http/src/Server.php(227): React\Http\Server->getMaxRequestSize()
#2 phar:///tmp/phpstan-fixer/phpstan-fixer.phar/src/Command/DefaultCommand.php(197): React\Http\Server->__construct()
#3 phar:///tmp/phpstan-fixer/phpstan-fixer.phar/vendor/symfony/console/Command/Command.php(255): PHPStanFixer\Command\DefaultCommand->execute()
#4 phar:///tmp/phpstan-fixer/phpstan-fixer.phar/vendor/symfony/console/Application.php(1009): Symfony\Component\Console\Command\Command->run()
#5 phar:///tmp/phpstan-fixer/phpstan-fixer.phar/vendor/symfony/console/Application.php(273): Symfony\Component\Console\Application->doRunCommand()
#6 phar:///tmp/phpstan-fixer/phpstan-fixer.phar/vendor/sym in phar:///tmp/phpstan-fixer/phpstan-fixer.phar/vendor/react/http/src/Io/IniUtil.php on line 26
PHPStan Pro process exited with code 255.

php.ini's memory limit in the container shows 512M, which seems valid to me:

nitro@cms-3:/app$ php -i | grep "memory_limit"
memory_limit => 512M => 512M

Have tried various combinations of --memory-limit=512M to PHPStan with the same error.

If I try it without setting PHPSTAN_PRO_WEB_PORT, it appears to work fine, other than the fact that port 11111 isn't exposed in this Nitro container so I can't access it from the host machine.

nitro@cms-3:/app$ ./vendor/bin/phpstan analyze --verbose --pro
Note: Using configuration file /app/phpstan.neon.
 1168/1168 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100% < 1 sec

Used memory: 177.59 MB
Running in Docker? You need to do these steps in order to launch PHPStan Pro:

1) Set the PHPSTAN_PRO_WEB_PORT environment variable in the Dockerfile:
   ENV PHPSTAN_PRO_WEB_PORT=11111
2) Expose this port in the Dockerfile:
   EXPOSE 11111
3) Publish this port when running Docker:
   -p 127.0.0.1:11111:11111
4) Map the temp directory to a persistent volume
   so that you don't have to log in every time:
   -v ~/phpstan-pro:/tmp/phpstan-fixer

sh: 1: xdg-open: not found
Open your web browser at: http://127.0.0.1:46025
Press [Ctrl-C] to quit.

Not sure the best way to debug this, but open to suggestions!

Did PHPStan help you today? Did it make you happy in any way?

Love PHPStan!

@mergeable
Copy link

mergeable bot commented Aug 3, 2021

This bug report is missing a link to reproduction on phpstan.org.

It will most likely be closed after manual review.

@jasonmccallister
Copy link

Would be great to have a --port argument to the phpstan command as well instead of setting and environment variable.

@staabm
Copy link
Contributor

staabm commented Aug 12, 2021

Sounds like a issue in your config or in https://github.com/reactphp/http/blob/master/src/Io/IniUtil.php
The exception message contains the memory size given to it.

PHP Fatal error: Uncaught InvalidArgumentException: is not a valid ini size in phar:///tmp/phpstan-fixer/phpstan-fixer.phar/vendor/react/http/src/Io/IniUtil.php:26

It seems its a empty string or a space-only string or similar

phpstan relqted sources seem to be arround here, in case you want to investigate https://github.com/phpstan/phpstan-src/blob/181f75ce89a521aebc0336a61352b821645c738a/src/Command/FixerApplication.php#L349

@ondrejmirtes
Copy link
Member

There's an invalid value in your post_max_size php.ini directive.

@angrybrad
Copy link
Author

angrybrad commented Aug 12, 2021

@ondrejmirtes seems valid to me?

nitro@cms-3:/app$ php -i | grep "post_max_size"
post_max_size => 512M => 512M

If I put a memory.php with this as the contents:

echo ini_get('post_max_size').PHP_EOL;

Then I run php memory.php, from the CLI (which is what FixerApplication.php does), I get this:

nitro@cms-3:/app$ php memory.php
512M

But if I change it to:

echo escapeshellarg(ini_get('post_max_size')).PHP_EOL;

I get this:

nitro@cms-3:/app$ php memory.php
'512M'

Guessing the single quotes around 512M are the issue here?

The seme behavior happens whether it's post_max_size or memory_limit.

@ondrejmirtes ondrejmirtes reopened this Aug 12, 2021
@ondrejmirtes
Copy link
Member

I'll add some debugging to PHPStan Pro itself which should tell us more info. This piece of code is what's triggering that: https://github.com/reactphp/http/blob/cd36b4fa319f1296cb634743a600e3548e31d443/src/HttpServer.php#L316-L342

@angrybrad
Copy link
Author

Happy to test whatever you need me to!

@ondrejmirtes
Copy link
Member

I just added this piece of code to PHPStan Pro:

		try {
			$postMaxSize = ini_get('post_max_size');
			if ($postMaxSize === false) {
				$postMaxSize = '';
			}
			IniUtil::iniSizeToBytes($postMaxSize);
		} catch (\InvalidArgumentException $e) {
			$phpIni = php_ini_loaded_file();
			$output->writeln(sprintf(
				"PHPStan Pro is likely to crash because your php.ini (%s)\ncontains post_max_size directive with value %s which is invalid.",
				$phpIni !== false ? $phpIni : 'none',
				var_export(ini_get('post_max_size'), true)
			));

			return 1;
		}

So you should see it crash before running with this nice error message. If this message isn't printed and PHPStan Pro still crashes later with the exception stack trace from the original post then I don't know what's going on...

Make sure your PHPStan Pro is up to date by launching it and checking "About PHPStan Pro" in the user menu. You can force the update there.

@angrybrad
Copy link
Author

angrybrad commented Aug 17, 2021

nitro@cms-3:/app$ ./vendor/bin/phpstan analyze --memory-limit=1G --pro
Note: Using configuration file /app/phpstan.neon.
 1170/1170 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

Running in Docker? Don't forget to do these steps:
1) Publish this port when running Docker:
   -p 127.0.0.1:3002:3002
2) Map the temp directory to a persistent volume
   so that you don't have to log in every time:
   -v ~/.phpstan-pro:/tmp/phpstan-fixer

PHPStan Pro is likely to crash because your php.ini (/tmp/sYDDXP)
contains post_max_size directive with value '' which is invalid.
PHPStan Pro process exited with code 1.
nitro@cms-3:/app$

Looks like PHPStan copies the php.ini file into a temp folder and the value is getting lost during that copy? Maybe escapeshellarg doesn't work properly from a temp folder?

@ondrejmirtes
Copy link
Member

You can get around that if you disable Xdebug. PHPStan relaunches with the help of https://github.com/composer/xdebug-handler if it detects Xdebug so that it doesn't affect performance.

@angrybrad
Copy link
Author

@ondrejmirtes does PHPStan base this on detecting if the xdebug module is loaded? Or even if it's loaded, does it check if it's disabled? i.e.

CleanShot 2021-08-20 at 20 46 19@2x

@ondrejmirtes
Copy link
Member

@angrybrad I'm not sure, check what https://github.com/composer/xdebug-handler does.

@angrybrad
Copy link
Author

angrybrad commented Aug 25, 2021

https://github.com/composer/xdebug-handler/blob/main/src/XdebugHandler.php#L73-L78

In my case, I'm running xdebug 3.0.4. ini_get('xdebug.mode') returns develop (the default), but getenv('XDEBUG_MODE') returns off.

Based on that, XdebugHandler should consider xdebug "off".

Not sure if it's an issue in XdebugHandler, or PHPStan's implementation of it, unfortunately. I'll try to do some more testing to narrow it down.

@ondrejmirtes
Copy link
Member

PHPStan just calls ->check() on XdebugHandler, please ask in XdebugHandler's repo.

@angrybrad
Copy link
Author

Based on the conversation here this doesn't seem to be related to the XdebugHandler library, since we've verified that Xdebug is indeed disabled for my environment.

@angrybrad
Copy link
Author

There seem to be 3 odd things:

  1. On the PHPStan Pro side, it seems to be pulling php.ini information from the /tmp folder, even though the XdebugHandler library says it's not restarting and Xdebug is disabled.
  2. When it pulls from the /tmp folder it's getting an incorrect value.
  3. It only happens when PHPSTAN_PRO_WEB_PORT is set. If it's not set, it runs fine, but you can't access PHPStan Pro in the browser, because the default port 11111 isn't exposed.

Number 3 seems the most interesting to me, but as far as I can tell, the PHPStan Pro code isn't public, so I'm not sure what logic is around that environment variable.

PHPStan Pro is likely to crash because your php.ini (/tmp/sYDDXP)

In addition to printing out the path to the loaded php.ini file, can you copy the contents of it into a location that can be examined? That might expose something interesting.

@angrybrad
Copy link
Author

angrybrad commented Nov 30, 2021

A bit slow, but finally root-caused this!

The docker images we're using (for example https://github.com/craftcms/docker/tree/main/7.4) have custom php.ini files that get copied into the container: https://github.com/craftcms/docker/blob/main/7.4/craft-cms.ini

The values are read from environment variables. Whatever logic/library PHPStan Pro is using to check for valid values doesn't know how to parse when the values are environment variables.

If I hard-code them to actual values, it works as expected.

@ondrejmirtes
Copy link
Member

Hi, since the message Uncaught InvalidArgumentException: is not a valid ini size is about an empty string, to me it looks like ini_get() resolves this correctly, but the environment variable isn't defined when PHPStan Pro runs.

I just tried a fix, can you please try phpstan/phpstan dev-master to see if it helps? phpstan/phpstan-src@e61ad95 Thanks.

@angrybrad
Copy link
Author

That works! Thanks, @ondrejmirtes!

@github-actions
Copy link

github-actions bot commented Jan 2, 2022

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 2, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants