badges/shields · error · NotFound
not found
Error message
not found
What it means
The JetBrains IntelliJ base service throws a bare NotFound when the JetBrains plugin repository API responds with HTTP 200 but an empty `<plugin-repository>` XML body, which parses to `{ 'plugin-repository': '' }`. JetBrains signals 'plugin not found' this way instead of a 404, so the service translates it into a NotFound error. The comment in the source documents this quirk explicitly.
Source
Thrown at services/jetbrains/jetbrains-base.js:31
return !pluginId.match(/^([0-9])+/)
}
static _cleanPluginId(pluginId) {
const match = pluginId.match(/^([0-9])+/)
if (match) {
return match[0]
}
return pluginId
}
// xml
static _validate(data, schema) {
if (data['plugin-repository'] === '') {
// Note the 'not found' response from JetBrains IntelliJ API is:
// status code = 200,
// body = <?xml version="1.0" encoding="UTF-8"?><plugin-repository></plugin-repository>
// which is parsed to object = { 'plugin-repository': '' }
throw new NotFound()
}
return super._validate(data, schema)
}
async fetchIntelliJPluginData({ pluginId, schema }) {
const parserOptions = {
parseTagValue: false,
ignoreAttributes: false,
}
return this._requestXml({
schema,
url: `https://plugins.jetbrains.com/plugins/list?pluginId=${pluginId}`,
parserOptions,
})
}
// json
_parseJson(buffer) {View on GitHub (pinned to 766fd8bc89)
Solutions
- Copy the exact plugin XML id from the plugin's marketplace page (the id in its URL, e.g. /plugin/1347-Scala --> 'org.intellij.scala').
- If the plugin was unpublished, remove the badge or use the archived plugin id if still served.
- Retry the badge after confirming the plugin page loads on plugins.jetbrains.com.
Example fix
// before /jetbrains/plugin/d/1347-Scala // after /jetbrains/plugin/d/org.intellij.scala
Defensive patterns
Strategy: validation
Validate before calling
const JETBRAINS_PLUGIN_ID_RE = /^[A-Za-z0-9._-]+$/;
if (!JETBRAINS_PLUGIN_ID_RE.test(pluginId) || /^\d+-/.test(pluginId)) {
throw new Error(`pluginId must be the XML id (e.g. org.intellij.scala), got: ${pluginId}`);
} Type guard
function isNonEmptyPluginRepository(data) {
return data && typeof data === 'object' && typeof data['plugin-repository'] === 'object' && data['plugin-repository'] !== '';
} Try / catch
try {
const data = await getJetBrainsPluginBadge(pluginId);
} catch (e) {
if (e.name === 'NotFound') {
renderFallback(`plugin '${pluginId}' not found on JetBrains marketplace`);
} else throw e;
} Prevention
- Use the plugin's XML id from its marketplace URL, never the numeric id or display name
- Verify the plugin page exists on plugins.jetbrains.com before adding the badge
- Remember JetBrains returns 200 with an empty repository body for unknown plugins
When it happens
Trigger: Requesting plugin data (ratings/downloads/version) via fetchIntelliJPluginData for a pluginId that the JetBrains repository does not know — the API returns an empty plugin-repository element with status 200 and _validate throws NotFound.
Common situations: Wrong pluginId format in the badge URL (must be the XML id like 'org.intellij.scala', not the numeric plugin id or the plugin name); plugin unpublished/removed from the marketplace; typos or case mismatch in the id.
Related errors
AI-assisted analysis of badges/shields@766fd8bc89 (2026-08-30).
Data as JSON: /api/errors/8809f5fb89ace70a.
Report an issue: GitHub.