Homebrew-core: Unable to run node@8 and other software (e.g. php, ffmpeg) together

Created on 6 May 2020  路  17Comments  路  Source: Homebrew/homebrew-core

  • [X] ran brew update and can still reproduce the problem?
  • [X] ran brew doctor, fixed all issues and can still reproduce the problem?
  • [X] ran brew gist-logs <formula> (where <formula> is the name of the formula that failed) and included the output link?
  • [X] if brew gist-logs didn't work: ran brew config and brew doctor and included their output with your issue?

What you were trying to do (and why)

I update brew regularly. After several weeks, I returned to a project that requires node@8, and found that I could no longer execute it due to an update in icu4c. icu4c 66 is now linked for packages like php, ffmpeg, etc.

If I revert icu4c 64 by reinstalling via a previous commit (e.g. brew reinstall https://raw.githubusercontent.com/Homebrew/homebrew-core/896d1018c7a4906f2c3fa1386aaf283497db60a2/Formula/icu4c.rb), I can no longer run the other software that's linked to icu4c 66.

What happened (include command output)


Command output

% node
dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.64.dylib
Referenced from: /usr/local/opt/node@8/bin/node
Reason: image not found
zsh: abort node

What you expected to happen

Node to continue to work as expected.

Either with icu4c versioned (like php, node, and other packages),
or with node@8 updated to use icu4c 66.

Step-by-step reproduction instructions (by running brew install commands)

% brew install node@8
Warning: node@8 8.17.0 is already installed and up-to-date
To reinstall 8.17.0, run brew reinstall node@8

Most helpful comment

  1. User installs PostgreSQL or PHP or some other library depending on icu4c and receives the dependency icu4c at a certain version number
  2. In a few months, the user installs a different package (eg. Node) that also depends on icu4c, and receives a new version of icu4c (the old version is "cleaned up")
  3. The original package installed in 1. is broken because it depended on the old version

This sounds like a bug to me, or at least an edge case we did not plan for. It may even be "by design", I need to do more research on this. Let us more time to have a look at this.

This seems to be a pretty bad way to deal with dependencies. Making your users research the problem, find out it's an issue with Homebrew, and then go through these types of workflows below (taken from this Stack Overflow) is pretty hostile.

I mean, we are not paid for this. This project is open-source, we do this in our free time. And I do not believe we do hostile things to our users. Why would we?

I would like to remind you of our code of conduct https://github.com/Homebrew/.github/blob/master/CODE_OF_CONDUCT.md#code-of-conduct, and tone down a little bit, as I find the above comments quite aggressive towards us. This will surely not help get your issue fixed. Thanks.

All 17 comments

I'm not really sure how you expected this to work instead. You can't have 2 versions of icu4c installed so one set of software will be broken.

This class of problem causes a lot of confusion and grief by a lot of developers. Searching for this yields many pages on Stack Overflow like this one:

https://stackoverflow.com/questions/53828891/dyld-library-not-loaded-usr-local-opt-icu4c-lib-libicui18n-62-dylib-error-run

Searching a bit, there was a suggestion previously to allow installing multiple versions of icu4c: https://github.com/Homebrew/homebrew-core/issues/39567

It was closed before by @zbeekman with the notes that:

  1. All packages that depend on icu4c are upgraded (which is good, but requires reinstallation, in case you install a package afterwards)
  2. If you don't like this behavior, you can set HOMEBREW_NO_INSTALL_CLEANUP=1 in your environment but then you'll have to manually manage which old versions you want to cleanup and which you want to keep.
  3. Another idea is to brew pin icu4c but this is is likely to break something, so I would advise you not to do this

These are kind of ok, but it makes me wonder whether there couldn't be a better solution to the problem:

I guess what would be ideal is to to offer a way for users to opt out of cleanups only for certain on high-risk packages like icu4c (eg. with a conditional HOMEBREW_NO_INSTALL_CLEANUP=1).

Not sure what the API would look like, but maybe something like:

HOMEBREW_NO_INSTALL_CLEANUP=(icu4c otherpackage)

Actually your real issue is that we delete node on 2019-12-18 (179429e48757bbc149918df6555dbc0854c19880) with the following message:

node 8 is EOL end of the year 2019, and does not support Python 3.

This means that we do not update it anymore, and are not providing support for it.

If you really need this specific version, please have a look at: https://docs.brew.sh/How-to-Create-and-Maintain-a-Tap

There is not much more we can do, and we will probably not make many more changes to the cleanup logic which is seems to fine for 99% of our users.

What I was describing in my comment (and what is described in many links by many developers - this is not an isolated, 1% incident) wasn't an issue with an end of life Node.js, it was with the following workflow:

  1. User installs PostgreSQL or PHP or some other library depending on icu4c and receives the dependency icu4c at a certain version number
  2. In a few months, the user installs a different package (eg. Node) that also depends on icu4c, and receives a new version of icu4c (the old version is "cleaned up")
  3. The original package installed in 1. is broken because it depended on the old version

This seems to be a pretty bad way to deal with dependencies. Making your users research the problem, find out it's an issue with Homebrew, and then go through these types of workflows below (taken from this Stack Overflow) is not great.

Adding some logic for cleanup to read from an array instead of a boolean flag seems worth it in comparison.

At the very least, if Homebrew is not willing to fix this problem, they should provide a clear path for troubleshooting and solving these issues. Eg:

Throw an error message when installing a package that will break dependencies of another package - like in #2 in the comment above and make the user fix the issue (by running the command with the HOMEBREW_NO_INSTALL_CLEANUP=1?)

  1. User installs PostgreSQL or PHP or some other library depending on icu4c and receives the dependency icu4c at a certain version number
  2. In a few months, the user installs a different package (eg. Node) that also depends on icu4c, and receives a new version of icu4c (the old version is "cleaned up")
  3. The original package installed in 1. is broken because it depended on the old version

This sounds like a bug to me, or at least an edge case we did not plan for. It may even be "by design", I need to do more research on this. Let us more time to have a look at this.

This seems to be a pretty bad way to deal with dependencies. Making your users research the problem, find out it's an issue with Homebrew, and then go through these types of workflows below (taken from this Stack Overflow) is pretty hostile.

I mean, we are not paid for this. This project is open-source, we do this in our free time. And I do not believe we do hostile things to our users. Why would we?

I would like to remind you of our code of conduct https://github.com/Homebrew/.github/blob/master/CODE_OF_CONDUCT.md#code-of-conduct, and tone down a little bit, as I find the above comments quite aggressive towards us. This will surely not help get your issue fixed. Thanks.

  • User installs PostgreSQL or PHP or some other library depending on icu4c and receives the dependency icu4c at a certain version number
  • In a few months, the user installs a different package (eg. Node) that also depends on icu4c, and receives a new version of icu4c (the old version is "cleaned up")
  • The original package installed in 1. is broken because it depended on the old version

Can you try to provide something reproducible i.e. a series of git and brew invocations that produce this error message?

Note: if you run brew upgrade at any stage this would be fixed. That's not to say there's no room for improvement.

This sounds like a bug to me, or at least an edge case we did not plan for. It may even be "by design", I need to do more research on this. Let us more time to have a look at this.

Sounds reasonable, thank you.

tone down a little bit, as I find the above comments quite aggressive towards us

Sorry, I don't mean to take it out on you.

I understand that in open source there are time constraints and planning and sometimes tradeoffs need to be made. It sounded like the problem with shared dependencies getting cleaned up was being dismissed without consideration, which, when motivations are considered in good faith, is not what anyone wants, I think.

I am just advocating for the happy path / pit of success to be expanded here, so that broken software occurs less using shared dependencies in Homebrew.

if you run brew upgrade at any stage this would be fixed

Is this true also in case there isn't a newer version of the package installed, for example?

Eg. User already installed postgresql@12 a long time ago, with an old icu4c version. Does brew upgrade fix the links to the new version?

I thought that a user would at least need to do brew reinstall postgres and brew postgresql-upgrade-database (which incidentally, only has 1 upvote on SO):

Can you try to provide something reproducible i.e. a series of git and brew invocations that produce this error message?

Sure, I will try to come up with a reproducible workflow over the week some time. Maybe at that point, it makes sense to open a new issue.

Eg. User already installed postgresql@12 a long time ago, with an old icu4c version. Does brew upgrade fix the links to the new version?

Unless that is a formula that has been removed since, yes.

Eg. User already installed postgresql@12 a long time ago, with an old icu4c version. Does brew upgrade fix the links to the new version?

Yes. The "issue" if there is one here is that if you only ever run install but never upgrade we will sometimes upgrade dependencies for you but not do the same degree of checking/cleanup that we do with brew upgrade. I'll have a think about how best to improve that (no need to open a new issue).

Sure, I will try to come up with a reproducible workflow over the week some time. Maybe at that point, it makes sense to open a new issue.

Don't worry too much about it, was just wondering if you had one already ready.

Thanks!

The "issue" if there is one here is that if you only ever run install but never upgrade we will sometimes upgrade dependencies for you but not do the same degree of checking/cleanup that we do with brew upgrade. I'll have a think about how best to improve that (no need to open a new issue).

Aha, ok, interesting. Thanks!

By the way, didn't mention this yet: I really appreciate the work that the Homebrew team puts into everything. Makes system setup guides like ours at UpLeveled so much less complex! Kudos, amazing work.

@karlhorky you're welcome and thanks for the kind words! https://github.com/MikeMcQuaid/strap may be of interest to you (as it automates a bunch of those steps).

As for surfacing this while it's being worked on, should we re-open this issue? Or alternately I can create a new issue?

Yes, please open a issue in https://github.com/Homebrew/brew/issues

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sstadick picture sstadick  路  4Comments

ghostbar picture ghostbar  路  4Comments

daviderestivo picture daviderestivo  路  4Comments

gregvirgin picture gregvirgin  路  3Comments

xeoneux picture xeoneux  路  3Comments