phpstan-vscode
phpstan-vscode copied to clipboard
Add support for multiple config files based on a file pattern (different to order of precendence)
This issue exists to diverge this discussion to it's own issue
The problem:
With a very large project, PHPStan eats through your memory faster than you can say segfault. So if you were limited on memory, splitting your configs so that you stay within the limit of your hardware is a very valid choice. Especially in the context of CI/CD.
There is currently no way to allow this extension to use a different config file based on directory of the file that was saved.
PHPStan does already support this via the
parameters.pathsconfig. If you were wanting to scan multiple paths / config files at the same time I could just call PHPStan multiple times.phpstan analyse path/to/directory --configuration path/to/phpstan.neon & phpstan analyse path/to/another/directory --configuration path/to/another/phpstan.neon &
This is possible in the CLI of course, but not via this extension (I would have to awkwardly change the
phpstan.configFilesetting every time I switch between working onsrc/vstest/in my example. and this is exactly what I do, it is quite frustrating
Solution 1:
I propose a new setting where we can map our configs to directories.
this example would be mutually exclusive with phpstan.configFile
"phpstan.configFiles": {
"${workspaceFolder}/src/*": "${workspaceFolder}/src.phpstan.neon",
"${workspaceFolder}/test/*": "${workspaceFolder}/test.phpstan.neon",
},
Solution 2:
We could instead just read the parameters.paths & paramerers.excludePaths values in the PHPStan config files, since it is just using the fnmatch() function to interpret them, we could do the same process to receive the same result without needing to define a new setting.
Each entry is used as a pattern for the fnmatch() function.
- https://phpstan.org/config-reference#analysed-files
I do like solution 2 a lot more since it requires a lot less user effort and is less likely to go wrong. But I do have to say that I'm not super opposed to the idea anymore. A few challenges still that I'll have to think about and that this kind of hinges on:
- Currently there is the
phpstan.configFilesetting. This already allows for a comma-separated list of config files that the extension will try in order. I'm kind of wondering how this change would fit into that. I guess it could be deprecated andphpstan.configFilescould be an array. Although then you'd have an array of comma-separated lists... Or the already-existing comma-separated list could be turned into an array of config files through somephpstan.multipleConfigsboolean. I guess this is solvable though. - Getting the list of files in the
pathsconfig isn't too easy for a few reasons:- There is currently no JS implementation of a
.neonfile parser. There is one in PHP and in Python though so I guess I could build a new one using those as reference. Quite a hassle to build that though... - I'd have to also implement resolving of included config files. Not undoable but does add to the complexity and list of things that can go wrong
- There is currently no JS implementation of a
These are kind of the two biggest implementation issues. If it turns out that one of them is just really hard to find a solution for (or it is possible but really complex) then it's probably not worth it to implement this. If they turn out to be doable then it should be rather easy to implement.
So TLDR: I am open to the idea but will have to think about it a bit. Might take a while before this is implemented though since I am a bit busy in the coming weeks and since bug-fixes obviously take priority.
I'd prefer the mutually exclusive option to not impact current user setups (I'm pretty sure I have seen other extensions do this, so that your settings.json would report an issue should you try to use both.)
I would say phpstan.configFiles could just take an array with the same comma separated string parameters, that way you can still have your order of precedence defined yourself on a per-directory level and it wouldn't require a whole lot of rework.
"phpstan.configFiles": [
"${workspaceFolder}/src.phpstan.neon, ${workspaceFolder}/src.phpstan.neon.dist, ${workspaceFolder}/src.phpstan.dist.neon",
"${workspaceFolder}/test.phpstan.neon, ${workspaceFolder}/test.phpstan.neon.dist, ${workspaceFolder}/test.phpstan.dist.neon"
],
IE. having the below configured in settings.json is disallowed, only one option may be selected.
"phpstan.configFile": "${workspaceFolder}/src.phpstan.neon, ${workspaceFolder}/test.phpstan.neon",
"phpstan.configFiles": [
"${workspaceFolder}/src.phpstan.neon",
"${workspaceFolder}/test.phpstan.neon"
],
- In the above example when using the
phpstan.configFilesetting: onlysrc.phpstan.neonORtest.phpstan.neonwill be evaluated. In order of precedence. - Whereas using the
phpstan.configFilessetting: bothsrc.phpstan.neonANDtest.phpstan.neonwill be evaluated. it may be wise to stagger these such thattest.phpstan.neonruns aftersrc.phpstan.neonto prevent hammering the machine
There is currently no JS implementation of a .neon file parser. There is one in PHP
It could be worth just having a small PHP script that will take a .neon config file, parse the parameters.paths & paramerers.excludePaths keys and run them through the fnmatch() function. That way should this function change behaviour in any way, this extension behaviour will match that of PHPStan itself since we are following the exact same process. Presumably you already have the PHP side of things set up as this is how the extension is able to call PHPStan so you'd just need to json_encode() all the information you need, spit it out, and parse that in JS.
The compute shouldn't be that taxing at all for this, so shouldn't impact run time and could probably be done as a pre-task to every run of the extension.
As much as it pains me, I do understand the low priority. Thank you for all the effort, know that it is very much appreciated.
Hmm yeah I agree that using an array of comma-separated values is probably the best. I'm also considering just switching to configFiles but still reading from configFile as a form of backwards compatibility, but still deprecating the setting. Mutually exclusive settings can be a bit confusing, especially since VSCode settings don't give a great overview of the entire picture. Then new users can move to that config while existing users don't need to change anything and nothing will break.
Whereas using the phpstan.configFiles setting: both src.phpstan.neon AND test.phpstan.neon will be evaluated.
Maybe good to get the scenarios as to which one is evaluated when clear:
- I'd say that if I just made a change in
src/then only that one will be evaluated and when I make a change intest/only that one should be evaluated right? - I would say that
PHPStan: scan project for errorsshould evaluate both of them, indeed probably best to not do so at the same time but to queue them. - I think it would be nice to add a
PHPStan: scan **current** project for errorscommand (if multiple config files are used) that only scans the project belonging to the configFile that belongs to the file you currently have open. (if no file open or it's in no config, this errors)
It could be worth just having a small PHP script that will take a .neon config file, parse the parameters.paths & paramerers.excludePaths keys and run them through the fnmatch() function. That way should this function change behaviour in any way, this extension behaviour will match that of PHPStan itself since we are following the exact same process. Presumably you already have the PHP side of things set up as this is how the extension is able to call PHPStan so you'd just need to json_encode() all the information you need, spit it out, and parse that in JS.
I'm a bit wary of this for a couple of reasons:
- The extension will also need to be shipped with a
vendor/folder then. That folder will contain composer-installed packages that may or may not be compatible with the user's operating system.- This can be circumvented by running
composer installwhen installing the extension, but it's a very big assumption to make that composer is installed on the user's system. Then there's issues like corporate proxies, permission issues and what not. And I probably wouldn't like it if an extension is running a bunch of PHP code on-install.
- This can be circumvented by running
- We'd also be assuming that PHP is installed on the user's system (and in the system path). Of course this isn't that big of an assumption to make but given that quite a few users of this extension run it and PHPStan within some very purpose-built docker containers that don't contain a lot of binaries, that might not always be the case. There's also the case of windows where this is not trivial, as well as people using specific PHP binaries
/usr/bin/php8.3instead of justphp, which might also cause some issues.
I completely agree that this would be ideal and would be a great match to what PHPStan does, but I'm thinking this is likely to cause a lot of edge cases with system setups to pop up. Maybe simpler to just build a JS implementation of the neon parser (possibly porting it with :sparkles:AI:sparkles:) and keep it all in-extension.
Well I've just found a neon parser in JS so that's no longer a problem. That's pretty nice
I've implemented it and I think it works (tested it with the new test/multi-config-demo folder). Can you give it a try?
Sorry for the late response! For me whilst this does work, it doesn't really suit my purpose since I have certain folders as set up as different workspaces in vscode. I see that this extension doesn't support multi-root workspaces (and only supports the first workspace shown), but was wondering if we could have an override to enable per-workspace scans?
My phpstan config files point to these different roots, so even if we ran all of these phpstan processes on different workspaces at the same time: I wouldn't have any crosstalk. But it is not possible to do so atm.
I can see why you didn't support multi-root in the first place, with cache invalidation probably being a big drive, but if you configure your stan configs correctly to point to the right directories, then it should just work.
Hmm that does complicate things a bit, largely because configuration right now is all relative to the current workspace. But it may be doable to fit this into the current model. As multiple configs are now supported in this branch, it uses the currently scanned file to determine the neon file. It's not a massive stretch to also use that file to determine its workspace folder to base the config off of.
Some questions though to understand:
- Is every one of your (.neon file) projects a separate workspace or do you also have some workspaces with multiple neon files in them?
- How would configuration look? Would you have workspace folder A where you configure
phpstan.configFiles: ['foo/config.neon']and then another folder B where you have different settings? Or do you foresee more of a singlephpstan.configFiles: [{path: 'foo/config.neon', workspaceFolder: A}]etc-like config? (I'm not sure if the latter is even possible)
Is every one of your (.neon file) projects a separate workspace or do you also have some workspaces with multiple neon files in them?
I do have some projects with multiple neon files in them for scanning different directories of the same project. Wheras I have a separate application that is still a part of the same overall project, so it is a separate root workspace in vscode. https://code.visualstudio.com/docs/editor/multi-root-workspaces.
I could place all of my .neon config files from all of my projects in the new "phpstan.configFiles" setting, however only changes in the first workspace root will trigger this extension to start scanning. Wheras I would be looking for an override to allow it to trigger on changes to any workspace root.
in my workspace:
...
"folders": [
{
"name": "primary",
"path": "../primary"
},
{
"name": "secondary",
"path": "../secondary"
},
],
...
Any changes in the "../primary" directory will trigger phpstan scans, this will also scan the "../secondary" directory as expected (due to the new and shiny multi-config file support) - However nothing you ever do in the "../secondary" directory could trigger the extension to start a scan, even if your setup could handle it.
How would configuration look? Would you have workspace folder A where you configure phpstan.configFiles: ['foo/config.neon'] and then another folder B where you have different settings? Or do you foresee more of a single phpstan.configFiles: [{path: 'foo/config.neon', workspaceFolder: A}] etc-like config? (I'm not sure if the latter is even possible)
Most extension handle this with path mappings. For instance:
"phpunit.paths": {
"${workspaceFolder:primary}": "/var/www/primary",
"${workspaceFolder:secondary}": "/var/www/secondary",
}
It could be something like:
"phpstan.paths": {
"${workspaceFolder:primary}": [
"config/primary.1.neon",
"config/primary.2.neon",
"config/primary.3.neon"
],
"${workspaceFolder:secondary}": [
"config/secondary.src.neon",
"config/secondary.tests.neon"
]
}
Although just allowing the scan to be triggered from any workspace root sounds like a simpler solution that would also work for me :)
The new version actually doesn't seem to work as expected in terms of this feature, the scan never completes when I use more than one config, when each works individually on their own. See my attached video
https://github.com/user-attachments/assets/ed7b7bb5-4818-4c36-988f-6baa58c0954e
I've just added multi-workspace support, I think it works (I've tested it on a demo project and it worked). Could you give it a try?
Regarding the testing not succeeding when using multiple configs, could you send along the logs of the extension (Output panel, then PHPStan Language Server). I think that'll contain some more info.
Regarding my questioning of how to configure this, I did not know that VSCode allows for per-workspace settings that would then space multiple workspace roots. So indeed configuring it in the workspace settings is entirely fine. I've right now allowed for ${workspaceFolder:folderName} to be used to refer to specific workspace folder roots. You can use that to refer to config files etc.
This new version does start the scan against all the correct files, however the problems tab only displays issues that were discovered from the first config in the list.
In the below example, only issues from phpstan.3.neon.dist will be displayed, any issues in phpstan.2.neon.dist or phpstan.1.neon.dist are ignored by vscode even though I can see that there were issues that were reported by phpstan in the console.
"phpstan.configFiles": [
"${workspaceFolder:REDACTED}/build/phpstan/config/phpstan.3.neon.dist",
"${workspaceFolder:REDACTED}/build/phpstan/config/phpstan.2.neon.dist",
"${workspaceFolder:REDACTED}/build/phpstan/config/phpstan.1.neon.dist",
],
One other thing I have noticed is the status bar can be incorrect at times making it look like the process has stalled when it is waiting for another execution to complete, which you can only see when you hover over the status itself, perhaps this could be changed to only show the progress of the task that is taking the longest (with all the ones that have a higher % completed displaying on hover instead).
Ah yes, thanks for the report. Both of those should be fixed in this version:
More of the same unfortunately, works fine with the configs individually, then when both are entered it is perpetually spinning in the task tray with no real indication of anything going on in the console (where usually I can see the % scan going up, or instantly complete). Nothing happens until I remove one of the configs then ctrl+s another php file, when it will catch up and run against the single config just fine.
I've got a hunch as to what this might be. I've added some logging in this new version, could you run this and send me the logs again? It's important to check the logs for PHPStan Language Server and not PHPStan Client for this one. Thanks!
I just started looking into support for multiple config files and I stumbled upon this issue
Currently I work on a big laravel monorepo where there are a lot of folders in packages/ folder and each team is responsible for maintaining different packages.
To solve issue of PHPStan being slow for the whole project and using a lot of memory we decided to add .neon config for each package to speed things up. It also allows us to apply phpstan at different levels per package and team
.neon config location is
packages/<package>/phpstan.dist.neon
packages/<package>/phpstan.neon
I use this extension and I manually change phpstan.configFile when I work on different packages. Not ideal but it works for me. Only issue that I have is if I have to work cross package at the same time
I was wondering would it be possible for this extension to automatically detect closest phpstan.dist.neon and phpstan.neon file based on the current file path?
For example, if I'm editing packages/<package>/Infrastructure/Http/SomeController.php then this extension would look for .neon files in following location
packages/<package>/Infrastructure/Http/
packages/<package>/Infrastructure/
packages/<package>/
packages/
<project root>
@SanderRonde I'm willing to test the .zip file that you shared but I'm not sure how to install vscode extension from .zip file. Can you describe what I need to do to install it?
Thanks! If yoy rename the file to a .vsix file you can drag it into the extensions panel or hit the "install from vsix" button in the dots menu
I initially missed your earlier comment. I do like the idea of resolving based on current location. It's pretty close to what typescript, eslint and prettier do. I'll try to look into this idea some more since indeed configuring every neon file location for every package in a monorepo is quite terrible, and having it "just work" would be really nice.
(there might be some hurdles/issues to overcome but I'll see :))
Auto resolving configs would be really nice. Thanks for taking that into consideration
I've managed to install the extension. Thanks for the help!
I've also checked out the multiple-configs branch and loaded the multiple-config-demo folder in vscode. If you need any help with testing or you need any output let me know
As I mentioned before, my work monorepo is already setup with few .neon files so I can test with that too. Or I could maybe help you out to setup more examples in the multiple-config-demo folder
I never published vscode extension but I do know basic stuff about debugging extension so maybe I can also help with that if you need any output
Let me know how I can help with this
I've implemented it in the auto-resolve branch. Currently there are only two settings that matter:
phpstan.configFilespecifies the file name of your config files. For examplephpstan.neonwill do a workspace-find for**/phpstan.neon. This is a comma-separated list sophpstan.neon,phpstan.neon.distworks too. Since the default value of this setting is alreadyphpstan.neon,phpstan.neon.dist,phpstan.dist.neonyou probably won't have to touch thisphpstan.binPath(orphpstan.binCommand) points to a single binary to use for running PHPStan
Apart from that all resolving is done automatically. The current steps are:
- Find all config files in the workspace(s)
- Iterate through them in specified order (in the above example
phpstan.neonfiles come beforephpstan.neon.distfiles) - Iterate through
pathssettings - If the to-check file is included in any of the configs, that's the config we'll use
You can also keep tabs on whether resolving succeeded and which config file was found by hovering over the "language status" (as VSCode calls it) status bar item. You'll recognize it as the {}.
I went for finding all files in the workspace over walking up the tree since:
- That's also what TypeScript and ESLint do
- I've found there to be some projects (my workplace's) where not all files included in a neon file are in subfolders. That would make the tree-walk method kind of useless in those cases and you'd have to fall back to a project-wide search after all.
Would you mind testing it out on your monorepo? (@Sectimus I'm fairly certain this will work better in your case as well, basically achieving the same with way less configuration)
Thanks for the quick update. I just tested the 3.2.14. I installed the extension and then I reloaded the window. In the status bar I see PHPStan checking <spinner> and the "Language status" shows PHPStan resolving config <spinner>
Here is the Output tab
# PHPStan Language Server
[11/10/2024, 3:17:47 PM] [server] Language server ready
[11/10/2024, 3:17:48 PM] [file-watcher] Checking: New document active
[11/10/2024, 3:17:48 PM] [check:1] Check started for project
[11/10/2024, 3:17:50 PM] [server] PHPStan version: PHPStan - PHP Static Analysis Tool 1.8.11
# PHPStan Client
[11/10/2024, 3:17:47 PM] [client] Starting extension with configuration: {
"phpstan.singleFileMode": false,
"phpstan.binPath": "vendor/bin/phpstan",
"phpstan.binCommand": [],
"phpstan.configFile": "phpstan.neon,phpstan.neon.dist,phpstan.dist.neon",
"phpstan.paths": {},
"phpstan.dockerContainerName": "",
"phpstan.rootDir": "",
"phpstan.options": [],
"phpstan.enableStatusBar": true,
"phpstan.memoryLimit": "30G",
"phpstan.enabled": true,
"phpstan.projectTimeout": 300000,
"phpstan.timeout": 5000,
"phpstan.suppressTimeoutMessage": true,
"phpstan.showProgress": true,
"phpstan.showTypeOnHover": false,
"phpstan.enableLanguageServer": false,
"phpstan.ignoreErrors": [
"Xdebug: .*"
],
"phpstan.suppressWorkspaceMessage": false,
"phpstan.pro": false,
"phpstan.tmpDir": "",
"phpstan.checkValidity": true
}
[11/10/2024, 3:17:47 PM] [client] Initializing done
[11/10/2024, 3:17:47 PM] [client] Showing one-time messages (if needed)
[11/10/2024, 3:17:47 PM] [server] Language server ready
[11/10/2024, 3:17:47 PM] [server] Language server started
[11/10/2024, 3:17:48 PM] [file-watcher] Checking: New document active
[11/10/2024, 3:17:48 PM] [check:1] Check started for project
[11/10/2024, 3:17:48 PM] [status-bar] notification:' {"opId":0,"type":"new","tooltip":"Checking project"}
[11/10/2024, 3:17:48 PM] [status-bar] Showing status bar
[11/10/2024, 3:17:50 PM] [server] PHPStan version: PHPStan - PHP Static Analysis Tool 1.8.11
After around 5min I see that PHPStan checking is gone and I see following in Output tab
# PHPStan Language Server
[11/10/2024, 3:22:48 PM] [check:1] Check completed for project, errors= {"fileSpecificErrors":{},"notFileSpecificErrors":[]}
[11/10/2024, 3:22:48 PM] [check:1] PHPStan check timed out after 300000ms
and
PHPStan Client
[11/10/2024, 3:22:48 PM] [status-bar] notification:' {"opId":0,"result":"Killed","type":"done"}
[11/10/2024, 3:22:48 PM] [status-bar] Hiding status bar, last operation result = Killed
[11/10/2024, 3:22:48 PM] [status-bar] notification:' {"opId":0,"result":"Killed","type":"done"}
[11/10/2024, 3:22:48 PM] [status-bar] Hiding status bar, last operation result = Killed
[11/10/2024, 3:22:48 PM] [check:1] Check completed for project, errors= {"fileSpecificErrors":{},"notFileSpecificErrors":[]}
[11/10/2024, 3:22:48 PM] [check:1] PHPStan check timed out after 300000ms
After 10 min "Language status" still shows PHPStan resolving config <spinner>
EDIT: after 11min "Language status" is gone but there is no output for server or client
When I change and save some file same check starts again
In this comment you mention
- Iterate through paths settings
- If the to-check file is included in any of the configs, that's the config we'll use
What would be the order of config files to check for path? Will it
- start from root config and then go into sub-folder
- start from sub-folder and then go up towards root
Ahh not sure about the check timing out, will debug that later. Do you maybe have a repo on which I can reproduce it or is it not public?
What would be the order of config files to check for path?
This is not in any particular order. It's the order in which vscode returns the findFiles call result. I'd assume that there are no two configs containing the same files though right? (other than a dist variant ofcourse) Or is that the case for you? If so maybe bottom-up traversal could happen too.
Unfortunately repo is private. I'll check out the auto -resolve branch and try to debug on my side. Can you suggest a file and line where I should put a breakpoint? I might be able to tweak findFiles. In my work repo there are a lot of files for findFiles to scan if you take vendor, node_modules and few other folders that have bunch of files that probably shouldn't be scanned for neon files
I think ideally same path shouldn't be in 2 neon files. If you implement it that way it would be easy to tweak neon files to follow that. I would prefer sub-folder up to root approach but that's just something that fits my case nicely
Thanks a bunch! I think the easiest way to debug it is to find the logs and put a breakpoint there. For example it looks like it's stuck at the check-start log. So I'd put a breakpoint there and step through to see where it ends. Important to launch the Attach to server task as well to ensure the breakpoints in the language server are placed too. I have a hunch that it's stalling on this line and infinitely waiting for the promise but I'm not too sure, would be great if you can find out :)
I might be able to tweak findFiles
Not sure if this is necessary. I'm pretty sure VSCode already only includes files in the workspace (so not ignored files like vendor/ and node_modules/) so it should be relatively performant and correct.
Regarding the order in which checking happens, I do think that checking in a "random" order (determined by VSCode) is not the best. Will add some order of resolving later. Indeed probably bottom-up fits nicely.
Hey, sorry for the delay. I just got back to testing this
Second place that you proposed in server/src/lib/editorConfig.ts is called few times but it doesn't hang there and it returns normally
I've put the breakpoint in check-start log and it goes to this line
const result = await runningCheck.promise;
It spends most of the time on that line and after some time it goes to next line and I see result.status === 'Killed' and in the project output tab PHPStan Language Server I see following message
[11/18/2024, 4:31:14 PM] [check:1] Check completed for project, errors= {"fileSpecificErrors":{},"notFileSpecificErrors":[]}
I then changed logic in ConfigResolveLanguageStatus to only return one .neon file to see if there is any difference and if maybe all those phpstan.neon files are just taking too long on the legacy project
files: (await workspace.findFiles(params.pattern, '**/vendor/**', 1)).map(
with this change it only finds one single .neon file. But it still spends long time on runningCheck.promise and it still returns Killed
When I run that single phpstan config manually in terminal there is only 77 files to scan and it runs pretty fast - maybe in 5 seconds
I also checked what findFiles here returns and I see some .neon files from vendor/
vendor/dragonmantank/cron-expression/phpstan.neon
vendor/league/oauth1-client/phpstan.neon
vendor/jean85/pretty-package-versions/phpstan.neon
...
I found following github pages for those files
https://github.com/thephpleague/oauth1-client https://github.com/dragonmantank/cron-expression https://github.com/Jean85/pretty-package-versions
and composer require commands
composer require 'jean85/pretty-package-versions:^1.5 || ^2.0'
composer require league/oauth1-client
composer require dragonmantank/cron-expression
Let me know where should I look next
Thanks for looking into it, indeed those files were not being ignored, should be fixed now. (the docs even mention that these files are not excluded so my bad)
Regarding it stalling on that promise. That promise is the big promise that captures the entire check, could you put a breakpoint here? That is the actual contents of the check. Thanks so much!
Thanks for your help so far!
I had issue with debugging being really slow so I had to add
"debug.inlineValues": "off",
to my settings.json and now it's much better
I did some debugging and I found 2 issues and once I fixed those phpstan managed to run successfully
First, in one of the package folders I had phpstan.neon that was referencing non-existing phpstan.dist.neon. Since those are ignored in the .gitignore I didn't notice that there is no matching phpstan.dist.neon. I just recently started adding phpstan to packages and I guess I forgot to remove this file after testing it out. Luckily there was an error in output that pointed that out
Second, I debugged until shared/neon.ts:71 line
const parameters = neonFile.get('parameters');
and after few loops it would never reach line 72. I managed to find that it was parsing vendor/phpstan/phpstan-phpunit/rules.neon which has follwing content
rules:
- PHPStan\Rules\PHPUnit\AssertSameBooleanExpectedRule
- PHPStan\Rules\PHPUnit\AssertSameNullExpectedRule
- PHPStan\Rules\PHPUnit\AssertSameWithCountRule
- PHPStan\Rules\PHPUnit\MockMethodCallRule
- PHPStan\Rules\PHPUnit\ShouldCallParentMethodsRule
I noticed that it doesn't have
parameters:
so I added empty parameters:. After that extension managed to go trough and to finish spinner and processing
I didn't see any errors for missing parameters...
Awesome, thank you so much! Will fix this bug. It should indeed at least warn of a missing parameters field instead of silently failing.
Also good to know about the debugHints thing since I tend to step through and debug quite often as well.