{"record":{"id":"932e8d41c4f53d99","repo":"badges/shields","slug":"none","errorCode":null,"errorMessage":"none","messagePattern":"none","errorType":"exception","errorClass":"NotFound","httpStatus":null,"severity":"info","filePath":"services/puppetforge/puppetforge-module-endorsement.service.js","lineNumber":47,"sourceCode":"\n  static defaultBadgeData = { label: 'endorsement' }\n\n  static render({ endorsement }) {\n    let color\n    if (endorsement === 'approved') {\n      color = 'green'\n    } else if (endorsement === 'supported') {\n      color = 'brightgreen'\n    } else {\n      color = 'red'\n    }\n    return { message: endorsement, color }\n  }\n\n  async handle({ user, moduleName }) {\n    const { endorsement } = await this.fetch({ user, moduleName })\n    if (endorsement == null) {\n      throw new NotFound({ prettyMessage: 'none' })\n    }\n    return this.constructor.render({ endorsement })\n  }\n}\n","sourceCodeStart":29,"sourceCodeEnd":52,"githubUrl":"https://github.com/badges/shields/blob/766fd8bc89a90b8534dc573ab72dec30215ab1ec/services/puppetforge/puppetforge-module-endorsement.service.js#L29-L52","documentation":"The Puppet Forge module endorsement badge throws NotFound with message 'none' when the module's metadata from the Puppet Forge API has a null/undefined `endorsement` field. Endorsement is 'approved' or 'supported' for curated modules; most community modules have none, so this is an expected 'no data' outcome rather than a crash.","triggerScenarios":"Requesting the endorsement badge for a module whose Forge metadata lacks an endorsement value — i.e. any module that has not been approved/supported by Puppet.","commonSituations":"Using the badge on a community-authored module; module renamed so the wrong slug is resolved; module is unpublished or was never submitted for endorsement.","solutions":["Only use the endorsement badge for modules known to be 'supported' or 'approved' on Puppet Forge","Double-check the user/moduleName slug in the badge URL","If the module should be endorsed, contact Puppet or resubmit it for the Forge approval program"],"exampleFix":"// before\n/badge/puppetforge/endorsement/myuser/mymodule  (community module, no endorsement)\n// after\n/badge/puppetforge/endorsement/puppetlabs/puppetlabs-apt  (endorsed module)","handlingStrategy":"validation","validationCode":"const meta = await fetch(`https://forgeapi.puppet.com/v3/modules/${user}-${moduleName}`)\nconst { endorsement } = await meta.json()\nif (!endorsement) console.warn('module has no Forge endorsement — badge will show none')","typeGuard":"function isEndorsed(data) { return data != null && typeof data.endorsement === 'string' && data.endorsement.length > 0 }","tryCatchPattern":"try {\n  return await service.handle({ user, moduleName })\n} catch (err) {\n  if (err instanceof NotFound && err.prettyMessage === 'none') return null // no endorsement: expected\n  throw err\n}","preventionTips":["Only place the endorsement badge on supported/approved Forge modules","Handle the 'none' case as a normal no-data outcome, not a failure","Keep the user/module slug in sync with the Forge URL"],"tags":["badge","puppetforge","not-found"],"backgroundTag":"missing-upstream-metadata","analyzedSha":"766fd8bc89a90b8534dc573ab72dec30215ab1ec","analyzedAt":"2026-08-30T01:40:27.499Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}