badges/shields · error · NotFound

invalid user id format

Error message

invalid user id format

What it means

The Mastodon follower badge identifies a user by numeric account id. handle() validates that the id is numeric with isNaN(id); a non-numeric id cannot be a valid Mastodon account id, so it throws NotFound('invalid user id format') before any request is made.

Source

Thrown at services/mastodon/mastodon-follow.service.js:72

      message: metric(followers),
      style: 'social',
      link: [
        `https://${domain}/users/${username}`,
        `https://${domain}/users/${username}/followers`,
      ],
    }
  }

  async fetch({ id, domain }) {
    return this._requestJson({
      schema,
      url: `https://${domain}/api/v1/accounts/${id}/`,
    })
  }

  async handle({ id }, { domain = 'mastodon.social' }) {
    if (isNaN(id))
      throw new NotFound({ prettyMessage: 'invalid user id format' })
    domain = domain.replace(/^https?:\/\//, '')
    const data = await this.fetch({ id, domain })
    return this.constructor.render({
      username: data.username,
      followers: data.followers_count,
      domain,
    })
  }
}

View on GitHub (pinned to 766fd8bc89)

Solutions

  1. Use Mastodon's numeric account id (e.g. from https://mastodon.social/api/v1/accounts/lookup?account_name=user).
  2. Replace the username in the badge URL with that numeric id.
  3. Keep the domain parameter as the instance hostname without protocol.

Example fix

// before
/mastodon/follow/@Gargron.svg
// after
/mastodon/follow/2393.svg
Defensive patterns

Strategy: validation

Validate before calling

const mastodonId = '2393'
if (!/^\d+$/.test(mastodonId)) throw new Error('Mastodon badge requires a numeric account id, not a @username')

Type guard

const isMastodonId = (id) => typeof id === 'string' && /^\d+$/.test(id)

Try / catch

try {
  return await mastodonService.handle({ id }, { domain })
} catch (e) {
  if (e instanceof NotFound && e.prettyMessage === 'invalid user id format') {
    // resolve handle -> numeric id via /api/v1/accounts/lookup and retry
  }
  throw e
}

Prevention

When it happens

Trigger: Passing a username string (e.g. '@user' or 'user@example.social') instead of the numeric account id, or an empty/alphanumeric id, making isNaN(id) true.

Common situations: Users copying the handle from the profile URL instead of the numeric id (visible in the .json or via the account lookup API), or mistakenly believing Mastodon badges accept @user@domain handles.

Related errors


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