Skip to content

CLI silently creates 0-byte files when file downloads hit HTTP 429 rate limit #1245

Description

@Cataallysm9928

Bug Description

When downloading exercises, the CLI fetches each file individually via separate HTTP requests. When these per-file requests receive HTTP 429 (Too Many Requests) responses, the CLI silently creates 0-byte files instead of reporting an error or retrying. The overall download reports success ("Downloaded to /path/to/exercise") even though all files are empty.

This is particularly easy to trigger when downloading multiple exercises in sequence, since each exercise requires ~10-12 file downloads and the Exercism API enforces rate limits across all of them.

Steps to Reproduce

  1. Download several exercises in quick succession:
    for name in bird-watcher two-fer hello-world lasagna matching-brackets; do
      exercism download --exercise="$name" --track=javascript --force
    done
  2. Check the file sizes in the downloaded directories:
    ls -la ~/Exercism/javascript/bird-watcher/

Expected Behavior

  • The CLI should respect the Retry-After header and retry failed file downloads
  • At minimum, the CLI should fail with an error message when file downloads return 429, rather than silently creating empty files
  • The final "Downloaded to" message should not be printed if files were not actually written

Actual Behavior

  • The initial solution metadata request (to api.exercism.org) succeeds with HTTP 200
  • All subsequent per-file requests (to exercism.org/api/v1/solutions/<id>/files/<filename>) return HTTP 429 with Retry-After: 23
  • The CLI creates the directory structure and all files, but every file is 0 bytes
  • The CLI prints "Downloaded to /path/to/exercise" as if it succeeded
  • Exit code is 0 (success)

Verbose Output Evidence

With --verbose, the per-file requests clearly show 429 responses:

GET /api/v1/solutions/<id>/files/package.json HTTP/1.1
HTTP/2.0 429 Too Many Requests
Retry-After: 23
Content-Type: text/plain
Retry later

Yet the CLI still reports success.

Environment

  • CLI version: 3.5.8
  • OS: macOS 15.5 (Darwin 24.5.0, Apple Silicon)
  • Track: javascript (but likely affects all tracks)

Impact

This bug is especially problematic because:

  1. The silent failure makes it hard to diagnose — users see "Downloaded" and assume success
  2. Running tests on 0-byte exercise files produces confusing, unrelated errors
  3. The --force flag compounds the issue by deleting existing valid files before the (failing) re-download

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions