denoland/deno · error · Error

Either `node` or `range` must be provided when reporting an…

Error message

Either `node` or `range` must be provided when reporting an error

What it means

To support `jsr:` packages under the stock-tsc compatibility setup, deno downloads registry metadata JSON from npm.jsr.io (deliberately via raw `HttpClient::download` so it does not pollute user-visible download logs). The download step's failures are tolerated with a `continue`, but if bytes arrive that `serde_json::from_slice` cannot parse as JSON, this error fires — the endpoint returned 200 with a non-JSON body.

Solutions

  1. Retry — transient corruption usually resolves on a second run
  2. Inspect what the URL actually returns: `curl -sL <metadata-url> | head` (look for HTML/proxy pages)
  3. Disable/bypass HTTP interception for npm.jsr.io, or configure `--cert`/`DENO_CERT` for TLS-inspecting proxies
  4. If the registry itself is serving broken metadata, wait it out or pin affected jsr: deps to an older version

Example fix

# before
$ deno check main.ts
# Failed to parse metadata for @luca/flag: expected value at line 1 column 1

# after (proxy was returning an HTML block page)
$ curl -s https://npm.jsr.io/@luca/flag | head  # -> <html>...
# add npm.jsr.io to proxy bypass list, then:
$ deno check main.ts  # ok
Defensive patterns

Strategy: retry

Validate before calling

# Verify the registry serves real JSON from your environment before building
curl -fsSL https://npm.jsr.io/@luca/flag | jq -e 'has("versions")' >/dev/null \
  || echo 'registry/proxy is mangling metadata'

Try / catch

Wrap install/check in a retry loop (2-3 attempts with short backoff) keyed on /Failed to parse metadata/: a 200-with-garbage-body is usually transient proxy/CDU corruption. If all attempts fail, stop and investigate the network path (curl the metadata URL) rather than looping.

Prevention

When it happens

Trigger: Metadata fetch succeeds at the HTTP level but the body is not valid JSON: an intercepting corporate proxy or SSL-inspection appliance returning an HTML block page with 200, a corrupted/truncated response from the registry, or an outage page served instead of the metadata document.

Common situations: Corporate proxies and Zscaler-style interception; flaky CI networks corrupting large responses; npm.jsr.io incidents; caching layers serving stale/broken bodies.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/dd37f7109a3a1c8b. Report an issue: GitHub.

Appendix: source

Thrown at cli/js/40_lint.js:386

    this.filename = fileName;
    this.sourceCode = new SourceCode(ctx);
  }

  getFilename() {
    return this.filename;
  }

  getSourceCode() {
    return this.sourceCode;
  }

  /**
   * @param {Deno.lint.ReportData} data
   */
  report(data) {
    const range = data.node ? data.node.range : data.range ? data.range : null;
    if (range == null) {
      throw new Error(
        "Either `node` or `range` must be provided when reporting an error",
      );
    }

    const start = range[0];
    const end = range[1];

    if (start > end) {
      throw new RangeError(
        `Invalid range. Start value is bigger than end value: [${start}, ${end}]`,
      );
    }

    /** @type {Deno.lint.Fix[]} */
    const fixes = [];

    if (typeof data.fix === "function") {
      const fixer = new Fixer();

View on GitHub (pinned to 9ad36f7a2c)