Skip to content

fix(cli): Fix waitPort to ensure FRAMEWORK_PORT_TIMEOUT_MS is respected - #8611

Open
McLeodSean wants to merge 1 commit into
netlify:mainfrom
McLeodSean:fix/dev-times-out-too-soon
Open

McLeodSean wants to merge 1 commit into
netlify:mainfrom
McLeodSean:fix/dev-times-out-too-soon

Conversation

@McLeodSean

Copy link
Copy Markdown

Summary

Fixes #8610

netlify dev now waits the full 10-minute FRAMEWORK_PORT_TIMEOUT_MS for the framework port, instead of giving up after ~15.5s because of a hidden retry cap.

  • src/lib/wait-port.ts: the loop now ends only when timeout elapses, not after a fixed number of retries. Removed the maxRetries parameter. Back-off, socket handling and ECONNRESET handling are unchanged.
  • src/utils/framework-server.ts: removed the maxRetries argument (20).
  • tests/unit/lib/wait-port.test.ts (new): covers a late-opening port, a port that never opens, and a server that resets the connection (guards the ECONNRESET crash when using Netlify CLI with Node.js 24.x and Nuxt 4.x dev server #7747 fix).
 waitPort(port, host, timeout)
-  for attempt < maxRetries ?? ceil(timeout / 2000)
+  for each attempt
     if elapsed > timeout → { open: false }
     try connect → { open: true }
     catch → sleep min(100ms × attempt, 1s)

Why maxRetries was removed

#7772 replaced the wait-port package, which loops until timeout, and added maxRetries to try to fix CI tests that were timing out. When the port is closed, each attempt fails instantly, so 20 retries give out after ~15.5s, long before the 10-minute timeout. Without the cap, the default of ceil(timeout / 2000) retries still stops at ~4.9 min. No caller needs a retry count, so timeout is now the only limit.

Test trade-off: http-agent.ts was hit by the same cap: its 50s AGENT_PORT_TIMEOUT actually ended after ~20s. Now that it waits the full 50s, the existing test should return error when proxy is not available (unresolvable host) takes ~50s instead of ~20s. That's still within vitest's 90s testTimeout. I kept this PR to the timeout fix and didn't add fail-fast handling for unresolvable hosts. If the slower test is a problem for CI, it could mock waitPort, or ENOTFOUND could fail fast like the old wait-port package did. Happy to do either in a follow-up.

Repro

Run dev with: [dev] command = "sleep 20 && python3 -m http.server 3999", targetPort = 3999

  • Before: Error: Timed out waiting for port '3999' to be open after ~15s
  • After: ✔ #custom dev server ready on port 3999 at ~23s, proxy returns 200

For us to review and ship your PR efficiently, please perform the following steps:

  • Open a bug/issue before writing your code 🧑‍💻. This ensures we
    can discuss the changes and get feedback from everyone that should be involved. If you`re fixing a typo or
    something that`s on fire 🔥 (e.g. incident related), you can skip this step.
  • Read the contribution guidelines 📖. This ensures your code follows our style guide and
    passes our tests.
  • Update or add tests (if any source code was changed or added) 🧪
  • Update or add documentation (if features were changed or added) 📝
  • Make sure the status checks below are successful ✅

A picture of a cute animal (not mandatory, but encouraged)

@McLeodSean
McLeodSean requested a review from a team as a code owner October 12, 2026 06:21
@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: fa46af14-147e-49fb-93cd-9ae09767c5e7


📥 Commits

Reviewing files that changed from the base of the PR and between 31ed36f and 326b831.



📒 Files selected for processing (3)
  • src/lib/wait-port.ts
  • src/utils/framework-server.ts
  • tests/unit/lib/wait-port.test.ts


🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:



💤 Files with no reviewable changes (1)
  • src/utils/framework-server.ts


Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.




📝 Summary

Summary by CodeRabbit

  • Bug Fixes
    • Improved startup handling when a framework server’s port is not immediately available. The server now waits up to 10 minutes for the port to open, rather than checking for only a fraction of a second.
    • Port checks now report whether a connection succeeds or the configured wait period expires, including when the connection is reset.
📝 Summary

Walkthrough

waitPort no longer uses a retry-count limit. It retries until a connection succeeds or the timeout expires. The framework server now uses a 10-minute timeout. New unit tests cover delayed connections, reset connections, and ports that do not open.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: amun-sihra



Merge Risk: ⚪ Minimal · up to 326b8

Frameworks that bind their port late can now use the configured startup window. No actionable merge-blocking risk was identified.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 326b8

Longer waits preserve the existing connection checks and failure handling. No new destination or privilege is introduced, but readiness still accepts any listener at the configured address. Whether the longer window matters in environments shared with untrusted processes remains uncertain.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The inspected exposure is bounded to the configured framework loopback port and configured proxy destination within the invoking CLI process. Longer retries change timing, not destination selection or authority. Broader deployment and tenant isolation were not established.

Trust Boundaries and Controls

  • observed — Framework probes remain directed to localhost, and unavailable ports still cause startup failure. Proxy URL parsing, scheme restrictions and failure responses remain unchanged. These checks constrain configuration and availability; they do not authenticate the service answering the readiness probe.

Resilience and Maintainability Implications

  • observed — Attempts remain sequential, with per-call state rather than shared retry ownership. There is no cancellation interface in either revision, so callers abandoning a wait cannot explicitly stop it; the longer effective wait can prolong that inherited behavior.

Hardening Proposals

  • proposed — If development runs alongside untrusted local processes, consider application-specific readiness or process isolation rather than treating TCP availability as service identity. This is conditional hardening, not an established PR-introduced vulnerability.

Pre-merge checks | Passed 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check Passed Issue #8610 requires framework-port waiting to respect the configured timeout instead of a fixed retry cap. src/lib/wait-port.ts now retries until the elapsed timeout check returns { open: false }…
Out of Scope Changes check Passed The changes are limited to the waitPort retry behavior, its framework-server call site, and focused unit tests. These changes directly implement issue #8610 and provide regression coverage. No unrel…
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2…
Description check Passed The description clearly explains the waitPort timeout fix, the affected files, the tests, and the known test trade-off. It is directly related to the changeset.
Title check Passed The title clearly identifies the waitPort fix and the goal of respecting FRAMEWORK_PORT_TIMEOUT_MS.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR



  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@McLeodSean McLeodSean changed the title Fix waitPort to ensure FRAMEWORK_PORT_TIMEOUT_MS is respected fix(cli): Fix waitPort to ensure FRAMEWORK_PORT_TIMEOUT_MS is respected Oct 12, 2026
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.

netlify dev times out waiting for framework port after ~15s instead of 10 minutes

1 participant