Skip to content

bug(packages): interrupted-upgrade sentinel lifecycle broken (deleted on failure, never cleared after manual restore) #47

Closed

Description

@dipto0321

Describe the bug

internal/node/dist.go:109 fetches the nodejs.org manifest via http.Get(url), which uses http.DefaultClient — no timeout is set anywhere in the request path.

Failure scenario

If nodejs.org hangs, or a corporate proxy/firewall silently drops the connection (no RST), nodeup check/nodeup upgrade blocks forever with no way out except Ctrl-C. There's no automatic fallback to the offline cache when a request merely hangs (as opposed to erroring outright).

Related, same file

  • No retry/backoff on a failed fetch (a single transient 503/DNS blip fails the command outright, despite this apparently being part of the original design intent).
  • No context.Context threaded into the HTTP call (no http.NewRequestWithContext) — a live cmd.Context() from the CLI layer can't cancel an in-flight fetch even when the caller has one available.
  • saveToCache (dist.go:267-284) writes the cache data file and its .meta expiry file as two separate plain os.WriteFile calls with no atomicity — two concurrent nodeup invocations refreshing the cache simultaneously can produce a corrupted or mismatched cache.

Suggested fix

  • Use an http.Client with a sane timeout (e.g. 10-30s).
  • Thread ctx through via http.NewRequestWithContext and client.Do(req).
  • Add a small retry-with-backoff wrapper (2-3 attempts) around the fetch.
  • Make saveToCache atomic: write to a temp file in the same directory, then os.Rename over the target (matching the pattern already used correctly in internal/packages/sentinel.go).

Severity

High for the timeout (can hang forever with no recovery), Medium for the retry/context/atomicity items.

Activity

  1. dipto0321 commented on Jul 3, 2026

    @dipto0321
    OwnerAuthor

    Closed as duplicate: this title describes the bug fixed in #46 (commit 16b9ab8, PR #81). The body of this issue is shifted up by one relative to the title and actually describes the unrelated node.js manifest fetch bug, which is filed again as #48 — closing this ticket and leaving #48 open for that work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions