What would you like Renovate to be able to do?
Support updating repositories which use Yarn v2
Describe the solution you'd like
It should require no custom config and "just work".
Describe alternatives you've considered
Additional context
https://dev.to/arcanis/introducing-yarn-2-4eh1 by @arcanis
@ViceIce have you been able to gather the list of things we need to do differently?
Migration guide: https://yarnpkg.com/advanced/migration
Things I've noted:
.yarnrc or .npmrc. This is particularly important when Renovate users need to authenticate with registriesrenovate/yarn container build is broken because the website bash-based install doesn't support pre-releasesHello, do you plan to work on this ? Is there something I can do to help ?
If you can create one or more repos to test against plus identify any shortcomings compared to today then that would help. I鈥檓 not using v2 yet so don鈥檛 have personal experience to reflect on
I have this repo: https://github.com/christophehurpeau/pob-eslint-config
And how are Renovate PRs wrong today? What鈥檚 missing?
There's an error: https://github.com/christophehurpeau/pob-eslint-config/pull/116#issuecomment-586036038
I look at the log in app.renovatebot.com/dashboard and the real error seems to be: Error: Unsupported option name (\"--ignore-scripts\")
(branch="renovate/pob-dependencies")
DEBUG: lock file error(branch="renovate/pob-dependencies")
{
"cmd": "npm i -g -C ~/.npm/[email protected] [email protected] && yarn install --ignore-scripts --ignore-engines --ignore-platform --mutex network:31879 && ~/.npm/[email protected]/bin/lerna bootstrap --no-ci -- --ignore-scripts --ignore-engines --ignore-platform --mutex network:31879",
"err": {
"killed": false,
"code": 1,
"signal": null,
"cmd": "npm i -g -C ~/.npm/[email protected] [email protected] && yarn install --ignore-scripts --ignore-engines --ignore-platform --mutex network:31879 && ~/.npm/[email protected]/bin/lerna bootstrap --no-ci -- --ignore-scripts --ignore-engines --ignore-platform --mutex network:31879",
"stdout": "/home/ubuntu/.npm/[email protected]/bin/lerna -> /home/ubuntu/.npm/[email protected]/lib/node_modules/lerna/cli.js\n+ [email protected]\nupdated 1 package in 35.127s\nUnknown Syntax Error: Unsupported option name (\"--ignore-scripts\").\n\n$ yarn install [--json] [--immutable] [--immutable-cache] [--check-cache] [--inline-builds] [--cache-folder #0]\n",
"stderr": "npm WARN deprecated [email protected]: request has been deprecated, see https://github.com/request/request/issues/3142\n",
"message": "Command failed: npm i -g -C ~/.npm/[email protected] [email protected] && yarn install --ignore-scripts --ignore-engines --ignore-platform --mutex network:31879 && ~/.npm/[email protected]/bin/lerna bootstrap --no-ci -- --ignore-scripts --ignore-engines --ignore-platform --mutex network:31879\nnpm WARN deprecated [email protected]: request has been deprecated, see https://github.com/request/request/issues/3142\n",
"stack": "Error: Command failed: npm i -g -C ~/.npm/[email protected] [email protected] && yarn install --ignore-scripts --ignore-engines --ignore-platform --mutex network:31879 && ~/.npm/[email protected]/bin/lerna bootstrap --no-ci -- --ignore-scripts --ignore-engines --ignore-platform --mutex network:31879\nnpm WARN deprecated [email protected]: request has been deprecated, see https://github.com/request/request/issues/3142\n\n at ChildProcess.exithandler (child_process.js:295:12)\n at ChildProcess.emit (events.js:210:5)\n at ChildProcess.EventEmitter.emit (domain.js:476:20)\n at maybeClose (internal/child_process.js:1021:16)\n at Process.ChildProcess._handle.onexit (internal/child_process.js:283:5)"
},
"type": "lerna",
"lernaClient": "yarn"
}
I'm not sure that the app is using Yarn v2 already, but in that case that error message is extra concerning
All such settings are now expected to be kept within the yarnrc or the environment, so that they affect all commands and not only the one running now. In this case you'd replace --ignore-scripts with YARN_ENABLE_SCRIPTS=0 in the env.
(Note that the engine and platform checks haven't been implemented yet but will generate warnings, not errors, so you won't need options or settings)
so the problem is on this line: https://github.com/renovatebot/renovate/blob/92722fc00c88e52a854a95b02a622198ba1c3741/lib/manager/npm/post-update/yarn.ts#L91 ? does YARN_ENABLE_SCRIPTS=0 is also supported in yarn 1 ?
As far as I can tell, yep!
does
YARN_ENABLE_SCRIPTS=0is also supported in yarn 1 ?
No, it's 2.x only (it can be semver-checked on yarn --version).
So I tried the latest release and there is another issue: the yarn.lock is not updated.
There is this warning in the logs:
DEBUG: Warning: Exception parsing yarn.lock
{
"filePath": "yarn.lock",
"err": {
"message": "Unknown token: { line: 3, col: 2, type: 'INVALID', value: undefined } 3:2 in lockfile",
"stack": "SyntaxError: Unknown token: { line: 3, col: 2, type: 'INVALID', value: undefined } 3:2 in lockfile\n at Parser.unexpected (/home/ubuntu/renovateapp/node_modules/@yarnpkg/lockfile/index.js:5064:11)\n at Parser.parse (/home/ubuntu/renovateapp/node_modules/@yarnpkg/lockfile/index.js:5193:14)\n at parse (/home/ubuntu/renovateapp/node_modules/@yarnpkg/lockfile/index.js:5262:17)\n at Object.module.exports.exports.default (/home/ubuntu/renovateapp/node_modules/@yarnpkg/lockfile/index.js:4835:96)\n at Object.getYarnLock (/home/ubuntu/renovateapp/node_modules/renovate/dist/manager/npm/extract/yarn.js:9:43)\n at runMicrotasks ()\n at processTicksAndRejections (internal/process/task_queues.js:97:5)\n at async Object.getLockedVersions (/home/ubuntu/renovateapp/node_modules/renovate/dist/manager/npm/extract/locked-versions.js:16:43)\n at async postExtract (/home/ubuntu/renovateapp/node_modules/renovate/dist/manager/npm/extract/index.js:346:5)\n at async Object.extractAllPackageFiles (/home/ubuntu/renovateapp/node_modules/renovate/dist/manager/npm/extract/index.js:366:5)\n at async Object.extractAllDependencies (/home/ubuntu/renovateapp/node_modules/renovate/dist/workers/repository/extract/index.js:28:28)\n at async Object.extractAndUpdate (/home/ubuntu/renovateapp/node_modules/renovate/dist/workers/repository/process/extract-update.js:12:26)\n at async Object.renovateRepository (/home/ubuntu/renovateapp/node_modules/renovate/dist/workers/repository/index.js:34:61)\n at async renovateRepository (/home/ubuntu/renovateapp/app/worker/index.js:520:26)\n at async /home/ubuntu/renovateapp/app/worker/index.js:742:5"
}
}
Code: https://github.com/renovatebot/renovate/blob/master/lib/manager/npm/extract/yarn.ts#L1
I think we should use @yarnpkg/parsers instead which supports both lockfile versions, but I don't know how I could adapt that line:
https://github.com/renovatebot/renovate/blob/master/lib/manager/npm/extract/locked-versions.ts#L21-L22
While waiting for the full support is there any special config/patch which could make renovate work with yarn berry even if it breaks yarn 1 support ?
No, but after some recent refactoring I think we鈥檙e in a much better position to implement this. So you have any example repo you can contribute towards testing?
@adriencohen We're waiting on yarnpkg/berry#1278 before we can fully support yarn v2. It's got a lot of attention right now, so I expect it won't be too much longer to wait.
Thank you for the update, unfortunately I can't share with you my repo but it's a yarn 2 monorepo and if you need to test some stuff i'll try on it and report to you.
Right now I have the issue mentionned above about the unknown parameters of yarn install
@rarkins, you'd asked for an example repo that exhibits the problems with yarn 2 repos.
This isn't a pure example repo, but it's a public repo and has a PR here from renovate bot that fails:
https://github.com/itaylor/bucket-ts/pull/2
The likely relevant parts in the logs in the renovate console are:
DEBUG: Detecting Lerna and Yarn Workspaces
DEBUG: Found monorepo packages with base path "."(packageFile="package.json")
{
"yarnWorkspacesPackages": [
"packages/*",
"tests"
]
}
DEBUG: Finding locked versions
DEBUG: Warning: Exception parsing yarn.lock
{
"filePath": "yarn.lock",
"err": {
"message": "Unknown token: { line: 3, col: 2, type: 'INVALID', value: undefined } 3:2 in lockfile",
"stack": "SyntaxError: Unknown token: { line: 3, col: 2, type: 'INVALID', value: undefined } 3:2 in lockfile\n at Parser.unexpected (/home/ubuntu/renovateapp/node_modules/@yarnpkg/lockfile/index.js:5064:11)\n at Parser.parse (/home/ubuntu/renovateapp/node_modules/@yarnpkg/lockfile/index.js:5193:14)\n at parse (/home/ubuntu/renovateapp/node_modules/@yarnpkg/lockfile/index.js:5262:17)\n at Object.exports.default (/home/ubuntu/renovateapp/node_modules/@yarnpkg/lockfile/index.js:4835:96)\n at Object.getYarnLock (/home/ubuntu/renovateapp/node_modules/renovate/dist/manager/npm/extract/yarn.js:10:43)\n at async Object.getLockedVersions (/home/ubuntu/renovateapp/node_modules/renovate/dist/manager/npm/extract/locked-versions.js:17:43)\n at async postExtract (/home/ubuntu/renovateapp/node_modules/renovate/dist/manager/npm/extract/index.js:368:5)\n at async Object.extractAllPackageFiles (/home/ubuntu/renovateapp/node_modules/renovate/dist/manager/npm/extract/index.js:389:5)\n at async Object.extractAllPackageFiles (/home/ubuntu/renovateapp/node_modules/renovate/dist/manager/index.js:37:21)\n at async Object.getManagerPackageFiles (/home/ubuntu/renovateapp/node_modules/renovate/dist/workers/repository/extract/manager-files.js:27:33)\n at async /home/ubuntu/renovateapp/node_modules/renovate/dist/workers/repository/extract/index.js:40:30\n at async Promise.all (index 1)\n at async Object.extractAllDependencies (/home/ubuntu/renovateapp/node_modules/renovate/dist/workers/repository/extract/index.js:39:28)\n at async Object.extract (/home/ubuntu/renovateapp/node_modules/renovate/dist/workers/repository/process/extract-update.js:59:24)\n at async Object.extractDependencies (/home/ubuntu/renovateapp/node_modules/renovate/dist/workers/repository/process/index.js:73:30)\n at async Object.renovateRepository (/home/ubuntu/renovateapp/node_modules/renovate/dist/workers/repository/index.js:39:56)\n at async renovateRepository (/home/ubuntu/renovateapp/app/worker/index.js:310:26)\n at async /home/ubuntu/renovateapp/app/worker/index.js:512:5"
}
}
And
DEBUG: Executing command(branch="renovate/pin-dependencies")
{
"command": "docker run --rm --name=renovate_node --label=renovate_child -v \"/mnt/renovate/gh/itaylor/bucket-ts\":\"/mnt/renovate/gh/itaylor/bucket-ts\" -v \"/tmp/renovate-cache\":\"/tmp/renovate-cache\" -v \"/home/ubuntu/.npmrc\":\"/home/ubuntu/.npmrc\" -e NPM_CONFIG_CACHE -e npm_config_store -w \"/mnt/renovate/gh/itaylor/bucket-ts\" renovate/node bash -l -c \"npm i -g yarn && sed -i 's/ steps,/ steps.slice(0,1),/' /home/ubuntu/.npm-global/lib/node_modules/yarn/lib/cli.js && yarn install --ignore-engines --ignore-platform --network-timeout 100000 --ignore-scripts\""
}
DEBUG: lock file error(branch="renovate/pin-dependencies")
{
"err": {
"killed": false,
"code": 1,
"signal": null,
"cmd": "docker run --rm --name=renovate_node --label=renovate_child -v \"/mnt/renovate/gh/itaylor/bucket-ts\":\"/mnt/renovate/gh/itaylor/bucket-ts\" -v \"/tmp/renovate-cache\":\"/tmp/renovate-cache\" -v \"/home/ubuntu/.npmrc\":\"/home/ubuntu/.npmrc\" -e NPM_CONFIG_CACHE -e npm_config_store -w \"/mnt/renovate/gh/itaylor/bucket-ts\" renovate/node bash -l -c \"npm i -g yarn && sed -i 's/ steps,/ steps.slice(0,1),/' /home/ubuntu/.npm-global/lib/node_modules/yarn/lib/cli.js && yarn install --ignore-engines --ignore-platform --network-timeout 100000 --ignore-scripts\"",
"stdout": "/home/ubuntu/.npm-global/bin/yarn -> /home/ubuntu/.npm-global/lib/node_modules/yarn/bin/yarn.js\n/home/ubuntu/.npm-global/bin/yarnpkg -> /home/ubuntu/.npm-global/lib/node_modules/yarn/bin/yarn.js\n+ [email protected]\nadded 1 package in 1.772s\nUnknown Syntax Error: Unsupported option name (\"--ignore-platform\").\n\n$ yarn install [--json] [--immutable] [--immutable-cache] [--check-cache] [--inline-builds]\n",
"stderr": "",
"message": "Command failed: docker run --rm --name=renovate_node --label=renovate_child -v \"/mnt/renovate/gh/itaylor/bucket-ts\":\"/mnt/renovate/gh/itaylor/bucket-ts\" -v \"/tmp/renovate-cache\":\"/tmp/renovate-cache\" -v \"/home/ubuntu/.npmrc\":\"/home/ubuntu/.npmrc\" -e NPM_CONFIG_CACHE -e npm_config_store -w \"/mnt/renovate/gh/itaylor/bucket-ts\" renovate/node bash -l -c \"npm i -g yarn && sed -i 's/ steps,/ steps.slice(0,1),/' /home/ubuntu/.npm-global/lib/node_modules/yarn/lib/cli.js && yarn install --ignore-engines --ignore-platform --network-timeout 100000 --ignore-scripts\"\n",
"stack": "Error: Command failed: docker run --rm --name=renovate_node --label=renovate_child -v \"/mnt/renovate/gh/itaylor/bucket-ts\":\"/mnt/renovate/gh/itaylor/bucket-ts\" -v \"/tmp/renovate-cache\":\"/tmp/renovate-cache\" -v \"/home/ubuntu/.npmrc\":\"/home/ubuntu/.npmrc\" -e NPM_CONFIG_CACHE -e npm_config_store -w \"/mnt/renovate/gh/itaylor/bucket-ts\" renovate/node bash -l -c \"npm i -g yarn && sed -i 's/ steps,/ steps.slice(0,1),/' /home/ubuntu/.npm-global/lib/node_modules/yarn/lib/cli.js && yarn install --ignore-engines --ignore-platform --network-timeout 100000 --ignore-scripts\"\n\n at ChildProcess.exithandler (child_process.js:303:12)\n at ChildProcess.emit (events.js:311:20)\n at ChildProcess.EventEmitter.emit (domain.js:482:12)\n at maybeClose (internal/child_process.js:1021:16)\n at Process.ChildProcess._handle.onexit (internal/child_process.js:286:5)"
},
"type": "yarn"
}
DEBUG: No updated lock files in branch(branch="renovate/pin-dependencies")
Hopefully this is helpful
I'm having this issue as well. Is there some estimate when this will be supported? I don't consider myself early adopter, would be nice to have this running!
@JamieMagee The linked issue has been fixed, and updates released. Are there more issues blocking this, that the community could help triage?
@mormahr You can follow #6045 to track progress on yarn v2 support.
This is marked as Done, but when I run it with the latest release in what I believe is a basic yarn 2 configuration, I'm still getting errors:
Specifically the yarn.lock files fail to be updated because renovate runs yarn with options that yarn v2 doesn't support:
DEBUG: Executing command(branch="renovate/typescript-4.x")
{
"command": "docker run --rm --name=renovate_node --label=renovate_child -v \"/mnt/renovate/gh/itaylor/bucket-ts\":\"/mnt/renovate/gh/itaylor/bucket-ts\" -v \"/tmp/renovate-cache\":\"/tmp/renovate-cache\" -v \"/home/ubuntu/.npmrc\":\"/home/ubuntu/.npmrc\" -e NPM_CONFIG_CACHE -e npm_config_store -w \"/mnt/renovate/gh/itaylor/bucket-ts\" renovate/node bash -l -c \"npm i -g yarn && sed -i 's/ steps,/ steps.slice(0,1),/' /home/ubuntu/.npm-global/lib/node_modules/yarn/lib/cli.js && yarn install --ignore-engines --ignore-platform --network-timeout 100000 --ignore-scripts\""
}
DEBUG: lock file error(branch="renovate/typescript-4.x")
{
"err": {
"killed": false,
"code": 1,
"signal": null,
"cmd": "docker run --rm --name=renovate_node --label=renovate_child -v \"/mnt/renovate/gh/itaylor/bucket-ts\":\"/mnt/renovate/gh/itaylor/bucket-ts\" -v \"/tmp/renovate-cache\":\"/tmp/renovate-cache\" -v \"/home/ubuntu/.npmrc\":\"/home/ubuntu/.npmrc\" -e NPM_CONFIG_CACHE -e npm_config_store -w \"/mnt/renovate/gh/itaylor/bucket-ts\" renovate/node bash -l -c \"npm i -g yarn && sed -i 's/ steps,/ steps.slice(0,1),/' /home/ubuntu/.npm-global/lib/node_modules/yarn/lib/cli.js && yarn install --ignore-engines --ignore-platform --network-timeout 100000 --ignore-scripts\"",
"stdout": "/home/ubuntu/.npm-global/bin/yarn -> /home/ubuntu/.npm-global/lib/node_modules/yarn/bin/yarn.js\n/home/ubuntu/.npm-global/bin/yarnpkg -> /home/ubuntu/.npm-global/lib/node_modules/yarn/bin/yarn.js\n+ [email protected]\nadded 1 package in 0.969s\nUnknown Syntax Error: Unsupported option name (\"--ignore-platform\").\n\n$ yarn install [--json] [--immutable] [--immutable-cache] [--check-cache] [--inline-builds]\n",
"stderr": "",
"message": "Command failed: docker run --rm --name=renovate_node --label=renovate_child -v \"/mnt/renovate/gh/itaylor/bucket-ts\":\"/mnt/renovate/gh/itaylor/bucket-ts\" -v \"/tmp/renovate-cache\":\"/tmp/renovate-cache\" -v \"/home/ubuntu/.npmrc\":\"/home/ubuntu/.npmrc\" -e NPM_CONFIG_CACHE -e npm_config_store -w \"/mnt/renovate/gh/itaylor/bucket-ts\" renovate/node bash -l -c \"npm i -g yarn && sed -i 's/ steps,/ steps.slice(0,1),/' /home/ubuntu/.npm-global/lib/node_modules/yarn/lib/cli.js && yarn install --ignore-engines --ignore-platform --network-timeout 100000 --ignore-scripts\"\n",
"stack": "Error: Command failed: docker run --rm --name=renovate_node --label=renovate_child -v \"/mnt/renovate/gh/itaylor/bucket-ts\":\"/mnt/renovate/gh/itaylor/bucket-ts\" -v \"/tmp/renovate-cache\":\"/tmp/renovate-cache\" -v \"/home/ubuntu/.npmrc\":\"/home/ubuntu/.npmrc\" -e NPM_CONFIG_CACHE -e npm_config_store -w \"/mnt/renovate/gh/itaylor/bucket-ts\" renovate/node bash -l -c \"npm i -g yarn && sed -i 's/ steps,/ steps.slice(0,1),/' /home/ubuntu/.npm-global/lib/node_modules/yarn/lib/cli.js && yarn install --ignore-engines --ignore-platform --network-timeout 100000 --ignore-scripts\"\n\n at ChildProcess.exithandler (child_process.js:303:12)\n at ChildProcess.emit (events.js:311:20)\n at ChildProcess.EventEmitter.emit (domain.js:482:12)\n at maybeClose (internal/child_process.js:1021:16)\n at Process.ChildProcess._handle.onexit (internal/child_process.js:286:5)"
},
"type": "yarn"
}
DEBUG: No updated lock files in branch(branch="renovate/typescript-4.x")
DEBUG: Branch timestamp: 2020-08-20T15:59:24.994Z(branch="renovate/typescript-4.x")
This can be seen in a public repository here: https://github.com/itaylor/bucket-ts/pull/7#issuecomment-679273276
I think this was also noted by @christophehurpeau in https://github.com/renovatebot/renovate/pull/6045#issuecomment-676466751.
Is there some way to work around it?
Reopening. Should hopefully be quick to fix.
It would be awesome if anybody can send us a pr with the required argument changes for yarn v2 馃檭
This was partly covered earlier in the thread: https://github.com/renovatebot/renovate/issues/5230#issuecomment-595133229
ignore-scripts is enableScripts: false in .yarnrc now, or an env variable from the command lineignore-platform is just... gone. I can't find any documentation on what it was doing beyond "Ignores platform checking", no mentions of it in the v2 repo, and only a few instances on Google of people using it. There aren't any config options in the .yarnrc docs for v2 matching "platform", at any rate.ignore-engines tosses up a deprecation notice:
YN0050: The --ignore-engines option is deprecated; engine checking isn't a core feature anymore
Few notes:
.yarnrc.yml](https://yarnpkg.com/configuration/yarnrc): Yarn 2 has changed the name of the configuration file from .yarnrc to .yarnrc.yml and allows configuring its name via an environment variable.pnp.* and .yarn/cache (offline cache, configurable via Yarnrc) are updated and need to be committed when dependencies are updated (#7220)With the current release of renovate 23.19.1, I'm able to get yarn 2 support working! 馃帀
However, it still doesn't work correctly out of the box, without using some undocumented configuration.
In order to make it work, I had to add to my renovate.json file:
"compatibility": {
"yarn": "2.x"
}
In the docs, yarn is not documented as being one of the options for "compatibility" (see https://docs.renovatebot.com/configuration-options/#compatibility ). In order to figure out that's what it needs, I had to go read the renovate code.
It would be much nicer if renovate could query yarn to determine what yarn version is used, instead of making me declare which version I'm using. I understand that this is complicated by the fact that the yarn global executable is a different version than the yarn executable that is checked into the project in the .yarn folder.
@itaylor Renovate is able to detect the Yarn version from its lockfile: https://github.com/renovatebot/renovate/blob/605346f51b4b07ede6053302a632d7ac9f974735/lib/manager/npm/extract/locked-versions.ts#L15-L27
@ylemkimon maybe it should use that when it goes to compute isYarn1 in post-update/yarn.ts
https://github.com/renovatebot/renovate/blob/fbd0fdd7decf839cedf4cc13d9faf6bfe10a7520/lib/manager/npm/post-update/yarn.ts#L50-L55
As the code works right now, the lockfile doesn't get regenerated and the renovate run ends with an error on yarn 2 unless you've specified a compatibility setting in the config that tells it to use yarn 2.
Thanks for the list and the PRs @ylemkimon.
I'm currently looking at the yarnrc/.yarnrc.yml issue.
@JamieMagee Could you check whether it still needs configuring compatibility manually with the latest version (>=23.29.1)?
@ylemkimon I'm still seeing the same issue when running the latest Renovate 23.31.2 against JamieMagee/bookshelf. Investigating now.
Okay, I've fixed it. The issue is that the compatibility was only being set for the first package.json that was detected, due to how this if/else statement was constructed.
isYarn1, and the following logic, was only being executed if the lockfile was _not_ found in the cache.
Here's a sample PR I just generated JamieMagee/bookshelf#15. I need to look at tests + coverage, but I will send out a PR shortly.
Opened PR at #7330
@ylemkimon My fix is in version 23.31.3. Can you give it a go and see if it works for you?
@JamieMagee Actually, my installation worked before. Probably the issue was with Yarn workspaces (monorepo) because mine was
a single package. I've created a demo monorepo and it seems to work! Thank you.
@ylemkimon Excellent! I fixed a bug no-one complained about yet 馃槄
I think that the basic scenarios for Yarn v2 should now be covered without any additional Renovate conviguration. However, the issues you detailed above are still an issue. Would you agree?
Yes #7220 is still an issue.
Otherwise a pipeline that uses yarn install --immutable --immutable-cache will fail. And it would require a manual commit with the new dependencies added.
@brummelte Looks like #7220 was approved waiting to be merged. I've merged in the latest changes from master, and will merge if all tests pass.
It seems to work well with yarn 2 in my case.
I've only noticed a minor inconvenience (#7584).
Most helpful comment
@ylemkimon Excellent! I fixed a bug no-one complained about yet 馃槄
I think that the basic scenarios for Yarn v2 should now be covered without any additional Renovate conviguration. However, the issues you detailed above are still an issue. Would you agree?