Skip to content

Restore Node 24 (and before) behavior as fs.existsSync() now throws deprecation warning - #474

Open
kroh wants to merge 3 commits into
lando:mainfrom
kroh:fix-node24-deprecation-warning
Open

Restore Node 24 (and before) behavior as fs.existsSync() now throws deprecation warning#474
kroh wants to merge 3 commits into
lando:mainfrom
kroh:fix-node24-deprecation-warning

Conversation

@kroh

@kroh kroh commented Jul 17, 2026

Copy link
Copy Markdown

The problem

Execution of lando results in the following error:

$ lando setup
[DEP0187] DeprecationWarning: Passing invalid argument types to fs.existsSync is deprecated
  (Use `node --trace-deprecation ...` to show where the warning was created)

What was wrong

Node 24 introduced deprecation DEP0187: fs.existsSync() now warns when passed anything that isn't a string/Buffer/URL. Older Node silently returned false. Lando relies on that old behavior in many places — it calls fs.existsSync(x) where x is often undefined or an object (e.g. plugin dirs that don't exist, config source objects). Each command bootstraps different subsystems, so different call sites fired.

The fix

Rather than guard dozens of individual call sites (fragile and incomplete), I added a single global shim at Lando's entry point at @lando/core/bin/lando:

const _existsSync = fs.existsSync;
fs.existsSync = function(p) {
  if (typeof p !== 'string' && !Buffer.isBuffer(p) && !(p instanceof URL)) return false;
  return _existsSync.apply(this, arguments);
};

This restores the pre-Node-24 semantics (non-path argument returns false), so behavior is unchanged, just no warning.

@netlify

netlify Bot commented Jul 17, 2026

Copy link
Copy Markdown

Deploy Preview for lando-core ready!

Name Link
🔨 Latest commit b00438d
🔍 Latest deploy log https://app.netlify.com/projects/lando-core/deploys/6a749bd371b52c0008e74716
😎 Deploy Preview https://deploy-preview-474--lando-core.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 80 (🔴 down 3 from production)
Accessibility: 89 (no change from production)
Best Practices: 92 (no change from production)
SEO: 90 (no change from production)
PWA: -
View the detailed breakdown and full score reports
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@AaronFeledy

Copy link
Copy Markdown
Member

Thanks for tracking this down! The Node 24 diagnosis looks right, and it should be possible to fix while retaining Node 20 compatibility. Could we avoid globally monkey-patching Node's fs module, though? That changes existsSync() for every dependency in the process and only applies when core is loaded through bin/lando.

I'd suggest a small explicit helper that returns false for non-path values, then use it at the permissive call sites. A regression test covering invalid values on Node 24 would also be helpful. That preserves the old behavior on Node 20 without changing the global API.

kroh and others added 2 commits August 5, 2026 08:13
Node 24 deprecated passing anything that is not a string, Buffer or URL to
fs.existsSync(). Older Node quietly returned false, which a number of lando
call sites relied on: they pluck optional keys off plugin and config objects
and just want a "is there a file there?" answer. On Node 24 those now emit a
DeprecationWarning to stderr on more or less every lando invocation.

Add utils/exists-sync.js, which returns false for non path-like values and
otherwise defers to fs.existsSync(). Also expose it as utils.existsSync so
plugins can use it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants