Skip to content

[Package Bug] mpkg loops forever fetching the listing when the index JSON has no packages key #750

Description

@vadi2

Package name: mpkg (v3.4)

Issue:

Brief summary

If the repository URL answers HTTP 200 with valid JSON that has no packages key, mpkg goes into an unguarded fetch loop and the Mudlet client becomes unusable. It never recovers, even after the repository starts serving a good listing again - the only way out is to kill Mudlet.

HTTP 404 and a non-JSON body are both handled cleanly (one "Failed to download package listing." and then the normal "Aborting, unable to read repository information." per command). So the missing guard is specifically the "valid JSON, wrong shape" case, which is what a proxy, a captive portal, or a future change to the listing format would produce.

Steps to reproduce

  1. Point mpkg.repository at a server that returns {"name":"no packages key here"} for mpkg.packages.json.
  2. Run mpkg update (or any command that calls mpkg.ready(), e.g. mpkg list).
  3. The client starts hammering the repository and stops responding.

The loop

mpkg.ready()                -- mpkg.packages exists, mpkg.packages['packages'] is nil -> false
  -> mpkg.updatePackageList()
    -> downloadFile()
      -> sysDownloadDone
        -> mpkg.eventHandler()
          -> mpkg.checkForUpgrades(true)
            -> mpkg.ready(true)   -- still false
              -> mpkg.updatePackageList(true)  -- back to the top

Nothing breaks the cycle, and every command that calls ready() starts another concurrent chain, so the request rate grows rather than staying at one-in-flight.

Error output

Measured with a local mirror of the real listing (one file swapped for a packages-less body), Mudlet driven headlessly:

  • ~23,000-26,000 mpkg.packages.json requests in ~3 minutes, on both clients tested
  • console fills with Aborting, unable to read repository information. Retrying package listing update. / Updating package listing from repository. / Package listing downloaded. repeating forever
  • both runs had to be SIGKILLed; switching the mirror back to a good listing did not stop the loop

Extra information

Reproduces identically on Mudlet 4.22.0 and current development (4.22.0-dev-b1fc20c19), so this is a package-side issue rather than a client regression. Found during a package backwards-compatibility sweep for the 5.0 release.

Related but not the same: #96 (suppressing repeated failure messages) - that suppresses the echo on the download-error path, whereas this loop runs entirely on the download-success path, so silentFailures never comes into play.

Fix ideas

  • Treat "downloaded, but the body has no packages array" as a failure rather than a success: reject it in the sysDownloadDone handler before assigning mpkg.packages, and reuse the existing failure message + silentFailures handling.
  • Guard mpkg.ready() so it cannot start a fetch while one is already in flight, and add a cool-down/backoff so a persistently bad listing retries on a timer instead of immediately.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions