anuraghazra/github-readme-stats · warning · MissingParamError

Missing params "username" make sure you pass the parameters

Error message

Missing params "username" make sure you pass the parameters in URL

What it means

Thrown by fetchWakatimeStats when the destructured username is falsy. Unlike the top-languages fetcher, this function takes an object ({ username, api_domain }), so the missing key yields undefined. The check `if (!username)` fires before the axios call, so this is a pure caller-contract error, identical in message to the top-languages variant because both use the shared MissingParamError class.

Source

Thrown at src/fetchers/wakatime.js:14

// @ts-check

import axios from "axios";
import { CustomError, MissingParamError } from "../common/error.js";

/**
 * WakaTime data fetcher.
 *
 * @param {{username: string, api_domain: string }} props Fetcher props.
 * @returns {Promise<import("./types").WakaTimeData>} WakaTime data response.
 */
const fetchWakatimeStats = async ({ username, api_domain }) => {
  if (!username) {
    throw new MissingParamError(["username"]);
  }

  try {
    const { data } = await axios.get(
      `https://${
        api_domain ? api_domain.replace(/\/$/gi, "") : "wakatime.com"
      }/api/v1/users/${username}/stats?is_including_today=true`,
    );

    return data.data;
  } catch (err) {
    if (err.response.status < 200 || err.response.status > 299) {
      throw new CustomError(
        `Could not resolve to a User with the login of '${username}'`,
        "WAKATIME_USER_NOT_FOUND",
      );
    }
    throw err;

View on GitHub (pinned to 54a7985aee)

Solutions

  1. Include a non-empty ?username=<wakatime-login> in the request URL, e.g. /api/wakatime?username=johndoe.
  2. When calling fetchWakatimeStats directly, pass { username: validatedNonEmptyString } in the props object.
  3. Validate the username at the API boundary and return a descriptive 400 before reaching the fetcher.

Example fix

// before
const stats = await fetchWakatimeStats({ username: req.query.username, api_domain });

// after
const username = req.query.username;
if (!username || !username.trim()) {
  return res.status(400).send("username query parameter is required");
}
const stats = await fetchWakatimeStats({ username: username.trim(), api_domain });
Defensive patterns

Strategy: validation

Validate before calling

// Validate the props object before invoking fetchWakatimeStats
function buildWakatimeProps(query) {
  const username = query?.username;
  if (typeof username !== "string" || username.trim() === "") {
    throw new Error("'username' is required for WakaTime stats");
  }
  return { username: username.trim(), api_domain: query?.api_domain };
}

const props = buildWakatimeProps(req.query);
const stats = await fetchWakatimeStats(props);

Type guard

/** @param {unknown} p */
function hasUsername(p) {
  return typeof p === "object" && p !== null &&
    typeof p.username === "string" && p.username.trim().length > 0;
}

if (!hasUsername(props)) {
  return res.status(400).send("username query parameter is required");
}

Try / catch

try {
  const stats = await fetchWakatimeStats({ username, api_domain });
} catch (err) {
  if (err instanceof MissingParamError && err.missedParams.includes("username")) {
    return res.status(400).send(err.message); // bad request, no retry
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling fetchWakatimeStats({}) or fetchWakatimeStats({ username: "" }). Via the HTTP API (api/wakatime.js:82), a GET /api/wakatime request that omits ?username= or passes ?username= empty, so req.query.username is undefined when the handler calls fetchWakatimeStats({ username, api_domain }).

Common situations: A WakaTime card URL missing the ?username= parameter; a template variable that was never substituted; a programmatic caller building the props object from a config that lacks the username field.

Related errors


AI-assisted analysis of anuraghazra/github-readme-stats@54a7985aee (2026-08-12). Data as JSON: /api/errors/25a2a4c3507edee6. Report an issue: GitHub.