badges/shields · error · InvalidParameter

invalid url

Error message

invalid url

What it means

The endpoint badge service validates the user-supplied url with new URL() before making a request. If parsing fails (malformed URL string), it throws InvalidParameter with prettyMessage 'invalid url'. This is an input-validation error on the badge query parameter, not a network failure.

Source

Thrown at services/endpoint/endpoint.service.js:190

      ),
    }
  }

  constructor(...args) {
    super(...args)
    const config = configModule.util.toObject()
    this._allowUnsecuredEndpointRequests =
      config?.public?.allowUnsecuredEndpointRequests || false
  }

  async handle(namedParams, { url }) {
    let protocol, hostname
    try {
      const parsedUrl = new URL(url)
      protocol = parsedUrl.protocol
      hostname = parsedUrl.hostname
    } catch (e) {
      throw new InvalidParameter({ prettyMessage: 'invalid url' })
    }
    if (protocol !== 'https:' && !this._allowUnsecuredEndpointRequests) {
      throw new InvalidParameter({ prettyMessage: 'please use https' })
    }
    if (blockedDomains.some(domain => hostname.endsWith(domain))) {
      throw new InvalidParameter({ prettyMessage: 'domain is blocked' })
    }

    const validated = await fetchEndpointData(this, {
      url,
      httpErrors,
      validationPrettyErrorMessage: 'invalid properties',
      includeKeys: true,
    })

    return this.constructor.render(validated)
  }
}

View on GitHub (pinned to 766fd8bc89)

Solutions

  1. Ensure the url parameter is a full absolute URL including scheme (https://...)
  2. URL-encode the url value (encodeURIComponent) when embedding it in a badge link
  3. Test the URL with new URL(url) locally to confirm it parses
  4. Remove trailing whitespace or stray characters from the configured URL

Example fix

// before
/badge/endpoint?url=api.example.com/data.json
// after
/badge/endpoint?url=https%3A%2F%2Fapi.example.com%2Fdata.json
Defensive patterns

Strategy: validation

Validate before calling

function isValidBadgeUrl(url) {
  try {
    const u = new URL(url)
    return Boolean(u.protocol && u.hostname)
  } catch {
    return false
  }
}
// if (!isValidBadgeUrl(cfg.url)) fix the URL before building the badge link

Type guard

function isParsedUrl(url) {
  try { new URL(url); return true } catch { return false }
}

Try / catch

try {
  const badge = await getEndpointBadge({ url: cfg.url })
} catch (e) {
  if (e.prettyMessage === 'invalid url') {
    console.error(`Malformed endpoint URL: ${cfg.url}`)
  } else throw e
}

Prevention

When it happens

Trigger: GET /badge/endpoint with a json?url= parameter that is not a parseable absolute URL: missing scheme, spaces or unencoded special characters, relative paths, or an empty url parameter.

Common situations: Forgetting https:// prefix; passing URLs with raw ampersands/quotes not URL-encoded in the badge link; configuration templates leaving the url placeholder unfilled.

Related errors


AI-assisted analysis of badges/shields@766fd8bc89 (2026-08-30). Data as JSON: /api/errors/d8bbfcc68fd37b29. Report an issue: GitHub.