Affected components
Fixed on both ends: the backend now always returns a valid (possibly empty) list for that field, and the confirmation screen no longer assumes it will be present. New bot submissions are working normally again. A postmortem will be published shortly.
Identified: a change shipped August 29th made bot lookups prefer Discord's own metadata endpoint over our previous provider. That faster path doesn't return a bot's public flags, and the confirmation screen wasn't expecting that field to ever be missing, crashing instead of just showing fewer badges. Because the faster path succeeds for nearly every public bot, this affected most new submissions, not an edge case.
We're investigating reports that the Add Bot confirmation screen crashes for most new bot submissions right after looking up a bot.
On August 29, 2026, we shipped a change to how bot submissions look up a bot's public metadata: instead of always going through a third-party provider (JAPI.rest), we started trying Discord's own application metadata endpoint first, falling back to JAPI only if that failed. Discord's endpoint is faster and doesn't depend on a third party staying up, but it doesn't return everything JAPI does, specifically, a bot's public flags (badges like Verified Bot or Bot HTTP Interactions) aren't included.
The code that builds a bot's metadata after a successful Discord lookup
simply never set that field, and a missing field in Go becomes null on
the wire rather than an empty list. The Add Bot confirmation screen
called .map() on it directly to render badges, assuming it would always
be a list. When it was null instead, the whole confirmation screen
crashed with a plain TypeError, blocking submission entirely.
Because Discord's own endpoint succeeds for essentially every public bot, this hit the majority of new bot submissions, not an edge case. Anyone trying to add a new bot between August 29th and September 1st would have gotten a crashed confirmation screen immediately after looking their bot up, with no way to continue. Browsing and viewing already-listed bots were unaffected; this was specific to the submission flow.
We don't have a way to retroactively count how many submission attempts failed, since a client-side crash like this one never reaches our servers as an error report. This gap is called out directly in the follow-up actions below.
A Go struct was being built across two different code branches (the fast
Discord path and the JAPI fallback path), and one field, the bot's public
flags, was only ever set on the fallback branch. A Go slice that's never
assigned defaults to nil, which serializes to JSON null, not [].
The frontend's .map() call had no null guard, so it assumed a field the
backend's own type declared as always present would, in fact, always be
present.
Caught via browser console errors surfaced during unrelated work, not by
any automated monitoring, this class of frontend crash doesn't reach our
backend logs or alerting at all. The exact same underlying issue
(prod/panel writes silently turning a missing array into null instead
of []) had already been found and fixed in a different part of the
codebase back on August 29th itself, but this occurrence, in the bot
metadata lookup, wasn't caught at the time.
null" as a standing review point
for any new endpoint that assembles a response across multiple
conditional branches, not just something to catch after the fact.