Problem/Motivation

Currently we only run phpstan on changed files. This was decided because it saves on costs one DrupalCI (adding the full analysis takes 1,5 minutes).
However failing early also saves costs, and we saw issues in deprecating modules where we would benefit from this.
Also there are some recent improvements in test runs, saving time in test run.

It However it is adviced to always run this on the entire project.
https://phpstan.org/blog/why-you-should-always-analyse-whole-project

Running the full analysis when not on DrupalCi requires some larger resources (or time, can take up to 10-15 minutes). Which makes this inpractical for core committers. Therefore it was agreed that when not on drupalCI we keep only the partial analysis.

Proposed resolution

Adjust script, to always run full analysis on DrupalCI. When not on drupalCi the commit-code script only runs a partial check. (To make sure that locally not on every commit a full phpstan analysis needs to be done).

Remaining tasks

Script adjusted.

Issue fork drupal-3259355

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

mallezie created an issue. See original summary.

mondrake’s picture

Unfortunately this in phpstan-partial.neon

parameters:
  reportUnmatchedIgnoredErrors: false

also prevents reporting items no longer in the baseline, not just the general ignores.

This means that the baseline will get out-of-sync if issues solve baseline items without also removing those form the baseline, and developers will not be notified.

See #3112290: Replace REQUEST_TIME in procedural code for example.

I think this is another element on the side of always running full check.

mallezie’s picture

I think i just saw a problem with only scanning a list of files.
From #2316941: Use the builder pattern to make it easier to create render arrays
There is following patch:
https://www.drupal.org/files/issues/2022-01-21/core-builder-pattern-2316...

This gives below result on phpstan.
https://www.drupal.org/pift-ci-job/2300923

If we take this change as an example:

diff --git a/core/lib/Drupal/Core/Layout/LayoutDefinition.php b/core/lib/Drupal/Core/Layout/LayoutDefinition.php
index d80a8720ca..fa9b83bda0 100644
--- a/core/lib/Drupal/Core/Layout/LayoutDefinition.php
+++ b/core/lib/Drupal/Core/Layout/LayoutDefinition.php
@@ -9,6 +9,7 @@
 use Drupal\Component\Plugin\Definition\PluginDefinition;
 use Drupal\Core\Plugin\Definition\DependentPluginDefinitionInterface;
 use Drupal\Core\Plugin\Definition\DependentPluginDefinitionTrait;
+use Drupal\Core\Render\Element\Image;
 
 /**
  * Provides an implementation of a layout definition and its metadata.
@@ -437,13 +438,12 @@ public function setIconMap($icon_map) {
   public function getIcon($width = 125, $height = 150, $stroke_width = NULL, $padding = NULL) {
     $icon = [];
     if ($icon_path = $this->getIconPath()) {
-      $icon = [
-        '#theme' => 'image',
-        '#uri' => $icon_path,
-        '#width' => $width,
-        '#height' => $height,
-        '#alt' => $this->getLabel(),
-      ];
+      $icon = Image::getBuilder()
+        ->setUri($icon_path)
+        ->setWidth($width)
+        ->setHeight($height)
+        ->setAlt($this->getLabel())
+        ->toRenderable();
     }
     elseif ($icon_map = $this->getIconMap()) {
       $icon_builder = $this->getIconBuilder()

This results in following phpstan error:

Running PHPStan on changed files.
 ------ --------------------------------------------------------------------- 
  Line   lib/Drupal/Core/Layout/LayoutDefinition.php                          
 ------ --------------------------------------------------------------------- 
  441    Call to static method getBuilder() on an unknown class               
         Drupal\Core\Render\Element\Image.                                    
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols  
 ------ --------------------------------------------------------------------- 

The reason the class is unknown is because it's added in this patch. But phpstan only scans the changed files, and does not scan the Image class, so it cannot see that this class exists.

longwave’s picture

Status: Postponed » Needs review

#3 makes sense, I don't see how we can work around this any other way.

mallezie’s picture

To add, on the testbot this takes 1'13" (if we start running it now, without the possible cache improvements.)

15:04:43 Running PHPStan on *all* files.

15:05:56
15:05:56 [OK] No errors
15:05:56
15:05:56
15:05:56 PHPStan: passed

longwave’s picture

Anyone concerned about the extra time needed on DrupalCI is welcome to review #3212346: Avoid hundreds of unnecessary installs when testing config entities which takes 4 minutes off a testbot run last time I checked.

mallezie’s picture

What might be still open is to see if we only need to run phpstan on gitlab CI. If this would cause locally a large delay when running on a local computer of all people running this script.

daffie’s picture

Can we link to the CR: https://www.drupal.org/node/3258232 and update it for this issue.

mondrake’s picture

I looked at the case in #3 but I cannot find anywhere the class that PHPStan considers missing - not in the patch, at least, so I'd tend to say that PHPStan is right...

PHPStan will work out of a fully built codebase, with the patch included, so even if changed files reference classes that are not part of the patch, still PHPStan would detect them AFAICS.

daffie’s picture

Status: Needs review » Reviewed & tested by the community

All code changes look good to me.
PHPStan does now a full code scan on all patches.
I leave it up to the committer to decide if the extra testbot run costs are acceptable.
Lets wait with updating the CR until after commit.
For me it is RTBC.

mallezie’s picture

@mondrake when rechecking my initial analysis was indeed incorrect, although the problem still stands.

The patch does the following:

diff --git a/core/lib/Drupal/Core/Layout/LayoutDefinition.php b/core/lib/Drupal/Core/Layout/LayoutDefinition.php
index d80a8720ca..fa9b83bda0 100644
--- a/core/lib/Drupal/Core/Layout/LayoutDefinition.php
+++ b/core/lib/Drupal/Core/Layout/LayoutDefinition.php
@@ -9,6 +9,7 @@
 use Drupal\Component\Plugin\Definition\PluginDefinition;
 use Drupal\Core\Plugin\Definition\DependentPluginDefinitionInterface;
 use Drupal\Core\Plugin\Definition\DependentPluginDefinitionTrait;
+use Drupal\Core\Render\Element\Image;
 
 /**
  * Provides an implementation of a layout definition and its metadata.
@@ -437,13 +438,12 @@ public function setIconMap($icon_map) {
   public function getIcon($width = 125, $height = 150, $stroke_width = NULL, $padding = NULL) {
     $icon = [];
     if ($icon_path = $this->getIconPath()) {
-      $icon = [
-        '#theme' => 'image',
-        '#uri' => $icon_path,
-        '#width' => $width,
-        '#height' => $height,
-        '#alt' => $this->getLabel(),
-      ];
+      $icon = Image::getBuilder()
+        ->setUri($icon_path)
+        ->setWidth($width)
+        ->setHeight($height)
+        ->setAlt($this->getLabel())
+        ->toRenderable();

Add a reference to Image class and use a (new) method getBuilder of the Image class. But indeed PHPstan (with the limited files) is correct that the image Class does not have this method.
However this method is added further in the patch.

diff --git a/core/lib/Drupal/Core/Render/Element/RenderElement.php b/core/lib/Drupal/Core/Render/Element/RenderElement.php
index 35814589b3..8aa918f7f4 100644
--- a/core/lib/Drupal/Core/Render/Element/RenderElement.php
+++ b/core/lib/Drupal/Core/Render/Element/RenderElement.php
@@ -7,6 +7,7 @@
 use Drupal\Core\Plugin\PluginBase;
 use Drupal\Core\Render\BubbleableMetadata;
 use Drupal\Core\Render\Element;
+use Drupal\Core\Render\RenderableInterface;
 use Drupal\Core\Url;
 
 /**
@@ -121,7 +122,47 @@
  *
  * @ingroup theme_render
  */
-abstract class RenderElement extends PluginBase implements ElementInterface {
+abstract class RenderElement extends PluginBase implements ElementInterface, RenderableInterface {
+
+  protected $renderable = [];
+
+  public static function getBuilder() {
+    return new static([], uniqid(), []);
+  }

To the RenderElement class. But since Image is not part of the items PHPStan scans, phpstan does not know that actualle Image extends RenderElement and thus that the function can be found in the RenderElement class.
It's that combination of issues what causes this IMO.

mondrake’s picture

#13 but Drupal\Core\Render\Element\Image is neither in the patch nor in the existing code, no? So how can you

use Drupal\Core\Render\Element\Image;

In other words, what happens to that patch if you remove the PHPStan checks? Wouldn't it fail in PHPUnit anyway?

Maybe I'm missing something here, sorry

mallezie’s picture

@mondrake Ow damn! you're right. PHPStan is correct here. Those two classes (Image and TextElement) are not existing.
Sorry for all the noise here. (At least we got a patch ready if we would decide to do a full scan). But the #3 argument off course is invalid in doing so.

mglaman’s picture

I found another reason why we need to run a full scan on all changes. I discovered #3260707: QuickEditJavascriptTestBase must be declared abstract this fix for a test base that is not abstract. Removing the class would cause the baseline to be out of date and PHPStan error (removing a baseline rule)

-
			message: "#^Drupal\\\\Tests\\\\BrowserTestBase\\:\\:\\$defaultTheme is required\\. See https\\://www\\.drupal\\.org/node/3083055, which includes recommendations on which theme to use\\.$#"
			count: 1
			path: modules/quickedit/tests/src/FunctionalJavascript/QuickEditJavascriptTestBase.php
mallezie’s picture

Wouldn't we solve the above by removing the phpstan partial file?

Mostly isn't this the guilty line here
reportUnmatchedIgnoredErrors: false

(I still agree on the full run, but above might be a good interim step?)

mondrake’s picture

#16 unfortunately it won’t work because in that case if any of the ignored errors (the general ones, not those in the baseline) does not occur in the changed files, it will be reported thus failing the scan.

mallezie’s picture

Forgot about that. Thx for explaining.

An option (although i think it's perhaps far fetched and not optimal) might be to do some baseline file scanning in the commit code script and see there if a changed file has an entry in the baseline file and flag it.
Say i changed file A, and file A is in the baseline, mention / flag it in the commit code script.

Although that would not be perfect. Say i have line 1 of file A in the baseline (line nrs are not in the baseline) and my patch touches lines 5-10 of that file, then i would need to fix the line 1 error in that file also while actually being not in scope for that change.

mglaman’s picture

That would be interesting! If the filename is found in the baseline via grep, run phpstan. I think that'd be a great compromise.

mondrake’s picture

#19 that's only going to work for baseline ignores though, not for the ones in phpstan.neon.dist, no?

catch’s picture

Status: Reviewed & tested by the community » Needs work

Running a full phpstan takes several minutes on my local machine via core/scripts/commit-code-check.sh, this is on a lenovo x1 carbon running ubuntu. Each thread growing up to 1gb+ memory usage. I have 16gb of ram and even starting with 12gb of ram free, it will still get down to swap by the end unless I hack phpstan.dist to reduce the maximum threads. Running phpstan with --debug -vvv it shows no particular file taking loads of memory, maybe one or two at 20mb each, but just a cumulative increase in memory usage as more files are parsed. Found a couple of upstream bugs that look similar (https://github.com/phpstan/phpstan/issues/3702 and https://github.com/phpstan/phpstan/issues/4072) - nothing very conclusive on those, and I didn't look into it further yet.

We run commit-code-check on every local core commit, so either caching or fixing the memory leak is necessary before adding this to core, otherwise it's going to make committing anything else at all quite tricky without workarounds. Maybe we could just enable the cache for the code check even though it'll be thrown away on DrupalCI, so that core committers can rely on it.

mallezie’s picture

Did some tests on locally running a full phpstan, and i do confirm this can take some time.
(My laptop is even slower then what catch describes here).

drupal-HEAD {10.0.x} $ time vendor/bin/phpstan analyze  --configuration=core/phpstan.neon.dist
 9754/9754 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
                                                                                                                        
 [OK] No errors                                                                                                         
                                                                                                                        
real    6m43.615s
user    22m41.589s
sys     0m23.777s

drupal-HEAD {10.0.x} $ time vendor/bin/phpstan analyze  --configuration=core/phpstan.neon.dist
 9754/9754 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
                                                                                                                        
 [OK] No errors                                                                                                         
                                                                                                                        
real    0m6.246s
user    0m3.436s
sys     0m1.516s

A cached one is luckily enough much faster. And in most cases this only takes changed files into account.

There are also a lot of possibilities when PHPStan invalidates the cache, so it runs a full scan again.

https://phpstan.org/user-guide/result-cache

  • Every 7 days
  • Changes in:
  • PHPStan version
  • PHP version
  • Loaded PHP extensions
  • Rule level
  • Configuration files hashes
  • Analysed paths
  • composer.lock files hashes
  • Stub files hashes
  • Bootstrap files hashes
  • Autoload file hash
  • Errors in the last run
  • Dependency tree of project files. If file A.php was modified since the last run, A.php and all the files calling or otherwise referencing all the symbols in A.php are analysed again.

Note: also when running with --debug the cache is not used.

So committers will sometimes have a full non-cached phpstan run. Question is, if this is acceptable for core committers, or do we need to move the phpstan analysis out of the core-commit script, and only run on CI?

By default the cache is stored at %tmpDir%/resultCache.php (/tmp/phpstan on my machine) so that needs to be writable i think.

catch’s picture

So committers will sometimes have a full non-cached phpstan run. Question is, if this is acceptable for core committers

On my machine, I ended up with a PHP fatal error at least twice, and eventually ended up forcing it to use less threads via hacking phpstan.neon.dist in order to be able to continue. It's not acceptable to make it impossible to commit a patch without hacking core...

I thought about a core patch to force the lower number of threads in phpstan.neon.dist for everyone, but... if you have 64g of ram instead of 16g on your laptop, you can probably afford more threads and get a quicker result, so that's not necessarily great either.

Question is, if this is acceptable for core committers, or do we need to move the phpstan analysis out of the core-commit script, and only run on CI?

The advantage of running things in the commit hooks (as we do for cspell etc.) is that we're less likely to introduce regressions when multiple patches are committed between DrupalCI test runs. However we obviously don't do that for full test runs, so it might not be the end of the world - but then I think a partial phpstan run would be better than nothing for the commit hooks.

mallezie’s picture

Status: Needs work » Needs review

Rebased the branch, and adjusted to run a full scan on CI, and a partial one otherwise.

mondrake’s picture

Status: Needs review » Reviewed & tested by the community

I think this is the best compromise possible ATM, thanks!

catch’s picture

Title: Always do a full phpstan analysis » [PP-1] Always do a full phpstan analysis
Related issues: +#3261539: Don't scan gzips
mondrake’s picture

Title: [PP-1] Always do a full phpstan analysis » Always do a full phpstan analysis
Priority: Normal » Critical

Critical, because as per #3261539-13: Don't scan gzips we are now not able to limit scanning to specific file extensions.

longwave’s picture

+1, because without this I think modifying LinkItemTest in a patch is not possible now, because it will cause PHPStan and in turn the script to crash.

mglaman’s picture

After reading #3261539-10: Don't scan gzips I see why this matters so much 😬, beyond stale concerns. So gzips were skipped but forced to be scanned due to how we passed files into PHPStan, bypassing exclusion?

mondrake’s picture

#29 that's my reading, yes

longwave’s picture

I think we have a case over in #3251754: Use sniff DrupalPractice.CodeAnalysis.VariableAnalysis on */tests/* that requires this change. PHPStan failed with:

 ------ --------------------------------------------------------------------- 
  Line   tests/Drupal/Tests/AssertHelperTraitTest.php                         
 ------ --------------------------------------------------------------------- 
  19     Class Drupal\Tests\AssertHelperTestClass not found.                  
         💡 Learn more at https://phpstan.org/user-guide/discovering-symbols   
 ------ --------------------------------------------------------------------- 

As far as I can see this is because the test in question does

    require_once __DIR__ . '/../../fixtures/AssertHelperTestClass.php';
    $class = new AssertHelperTestClass();

but PHPStan hasn't scanned that fixture (as it didn't change) and doesn't know that the class is located there.

mallezie’s picture

Need to test this, but at first sight @longwave that analysis looks correct.
However this will also fail the commit code script (when not run on ci) when a committer want's to commit that patch. In this case the only option for a committer would be to know to commit although the script fails, or run a full scan locally (which would require a committer to do manually, or hack the script). Not sure if this is really a problem.

mallezie’s picture

Not related to phpstan running partial or full. (both give same result).

In our phpstan config we have

excludePaths:
# Skip test fixtures.
- */tests/fixtures/*.php

This skips the AssertHelperTestClass class.

longwave’s picture

Oh, that is interesting, thanks for debugging that. I guess we need to be more specific in our exclude path settings?

catch’s picture

catch’s picture

Title: Always do a full phpstan analysis » [PP-1] Always do a full phpstan analysis
mondrake’s picture

Title: [PP-1] Always do a full phpstan analysis » Always do a full phpstan analysis
mglaman’s picture

I know one of the concerns was performance. phpstan-drupal has a performance improvement in dev-main waiting to be released: https://github.com/mglaman/phpstan-drupal/issues/318. It's not much but should improve reflection usage when the BrowserTestBaseDefaultThemeRule is checked (namespace preflight checks before checking ancestors to see if the class extends BrowserTestBase.) It's not tagged. But it's available if someone would like to try it locally.

mondrake’s picture

Status: Reviewed & tested by the community » Needs work
mondrake’s picture

Status: Needs work » Reviewed & tested by the community
alexpott’s picture

Priority: Critical » Normal

This is no longer critical.

xjm’s picture

Can we refactor the commit checks so that the full static analysis doesn't run on every commit, but the rest still do?

See:
https://github.com/alexpott/d8githooks/commit/abfe885830597f9a93be862658...

mallezie’s picture

@xjm not fully sure what you mean.
Phpstan here does a partial scan when not on DrupalCI (like it is now) and only does a full scan on DrupalCI.
Or would you like the partial phpstan scan also removed when not on DrupalCI.

xjm’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs issue summary update

@mallezie, if so, then the issue title and issue summary are out of date. :-) Thanks!

Edit: We also need those change record updates.

mallezie’s picture

Title: Always do a full phpstan analysis » Always do a full phpstan analysis on DrupalCI
Issue summary: View changes
mallezie’s picture

Tried to put issue summary back up to date.
For the change record https://www.drupal.org/node/3258232
Nothing needs to change here, this is still correct. This issue only adjust the core-commit-code script.

mallezie’s picture

Status: Needs work » Needs review
Issue tags: -Needs change record updates, -Needs issue summary update

Added some extra info the the previous change record.

mallezie’s picture

Rebased. This will probably fail now until #3278782: PHPStan baseline is out of sync is committed.

mallezie’s picture

mallezie’s picture

Still hoping to get this in, since it would fix some phpstan-baseline chasing issues.

There seems to be some performance improvements in the latest mglaman/phpstan-drupal version. So if we can update that one prior we can see a full scan takes much less time.

There do seem to be some quite good performance improvement in this upgrade.

After the update a full scan takes 1:15

15:00:21 Running PHPStan on *all* files.
15:01:36  ------ ------------------------------------------------------------------ 

While in #3278916: Update phpstan/phpstan to latest version a full scan takes 2:27

14:33:11 Running PHPStan on *all* files.

14:35:37  ------ ----------------------------------------------------------------------- 

So if we can get #3279840: Update mglaman/phpstan-drupal (and perhaps also #3278916: Update phpstan/phpstan to latest version) this might be acceptable as for the longer DrupalCI runtime (and thus costs).

mallezie’s picture

Now that the updates to phpstan and phpstan-drupal are in. I've rebased this, to let the bot run again.
From my side this is ready now. Giving in mind the performance improvements of phpstan-drupal, this might now be acceptable.

mallezie’s picture

Issue summary: View changes
alexpott’s picture

I think this change should leave in place the fullscan logic if phpstan files have changed. It makes the commit-code-check.sh logic better for committers like me. It makes this change smaller... basically do this instead:

  if [[ $PHPSTAN_DIST_FILE_CHANGED == "1" ]] || [[ "$DRUPALCI" == "1" ]]; then
mondrake’s picture

Status: Needs review » Needs work

NW for #53

mallezie’s picture

This was in place to then do a full scan on changes in both core/phpstan-baseline.neon and core/phpstan.neon.dist.

For the phpstan.neon.dist file, the configuration i think this makes sense. Do you also wan't this for 'each' baseline change? Since we committed a lot of items to the baseline (to stop introducing new ones), this might make it run locally more often than you would like?
If that's no issue, we might also do this for changes to the composer.lock files, and add that file to the list as well?

alexpott’s picture

@mallezie I would leave the logic for detecting whether to do a full run alone - it's fine as is. Most MRs do not change the baseline or the phpstan config.

mallezie’s picture

Status: Needs work » Needs review

Adjusted as requested.

mondrake’s picture

Status: Needs review » Reviewed & tested by the community

This will allow us to run full PHPStan analysis on all DrupalCI runs, while leaving it partial locally. Will save a lot of time in chasing baseline out-of-syncs, that happened already a few times since PHPStan was introduced. RTBC.

alexpott’s picture

I think we need to give @Mixologic the chance to chime in here. Maybe there is something we can set the the cache dir to that would allow Drupal CI to benefit from it.

I'm cautious about committing this because this means we'll be doing a full phpstan analysis on every test run even when non php code is changing. With a cache this could be near instantaneous but there are quite a few questions about how to generate that cache. Maybe this is something that'll be easier to do once with have everything running on gitlab and we can configure a daily job to generate the phpstan cache for each development branch that has phpstan.

mallezie’s picture

I can see the cautiousness.

As an intermediate step we might do #3259353: Run full phpstan on composer change first. When checking the issues where baseline problems were introduced. I saw following reasons.

* Removal of modules (which can be caught in the composer.lock change).
* Updates of phpstan and drupal-phpstan (which would also be caught)
* Some cases where issues ran against 9.x ci, but not to 10.x, that's something sitll to look out for.

Another option would be (but not sure how feasible) is to check if we can distinguish between a patch run on CI, and a nightly run, then we could do a full scan on the scheduled run. That might also help finding baseline issues earlier.

Mixologic’s picture

Drupalci testbots are ephemeral so they cannot benefit from any caches. Im not sure whether or not gitlabci is going to preserve caches since we will have a similar setup running there, with testrunners being created and destroyed on demand. Gitlab may keep caches on the main server (which, if it does means disk space we may need to plan for).

It's not ideal to have this add 2.5 minutes to every test run, mostly for the fact that we cant have this job run alongside other jobs in the pipeline, which we *will* get on gitlabci.

From my perspective, we can make this change now, and just take the cost hit until gitlabci, and then find ways to optimize later. Developer time $$ > testbot cost $$.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Funnily enough I think once the baseline is empty we could go back to running partial on CI because the only thing that has got out of date or been problematic has been the baseline. It definitely bugs me that we will run a scan when only js or css or txt or yml files are changing - partial scans are great for dealing with that case because they are so quick when all the files are excluded.

FWIW I think the "Developer time $$ > testbot cost $$" is not actually that clear here. By running PHPStan on every test run we make it something that every developer has to wait and care about when it fails.

That said @Mixologic has +1'd so let's go ahead because I don't have the will to discuss this anymore as that is wasting time too and I'm not sure how much it actually matters. FWIW all the linked issues that partial scans caused that were "critical" were actually solved or not down to partial scans.

Committed 6a27d76 and pushed to 10.0.x.

  • alexpott committed 6a27d76 on 10.0.x
    Issue #3259355 by mallezie, mondrake, catch, longwave, mglaman, alexpott...
neclimdul’s picture

Funnily enough I think once the baseline is empty we could go back to running partial on CI because the only thing that has got out of date or been problematic has been the baseline.

Maybe. I'm sure that's the case though because one of the reasons for a full run is to catch how change affects unmodified files. Like removing an interface might not break the changed file but have drastic impacts on untouched files.

FWIW I think the "Developer time $$ > testbot cost $$" is not actually that clear here.

I agree it complicated. Its surely nice skipping things when no php is modified but also super frustrating and a waste of other developers when pipelines break or chasing broken code testbot could have caught.

That said you mentioned commits that only touch js/css.Maybe we can do something with that in gitlab using the rules logic. Also, maybe the commit hook could do something similar as well looking for composer files, modules files, and php files and only running certain tests if those are modified?

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.