{"record":{"id":"f7527dc2ff8bd8c4","repo":"badges/shields","slug":"module-not-found-f7527d","errorCode":null,"errorMessage":"module not found","messagePattern":"module not found","errorType":"exception","errorClass":"NotFound","httpStatus":404,"severity":"error","filePath":"services/opm/opm-version.service.js","lineNumber":52,"sourceCode":"  async fetch({ user, moduleName }) {\n    const { res } = await this._request({\n      url: 'https://opm.openresty.org/api/pkg/fetch',\n      options: {\n        method: 'HEAD',\n        searchParams: {\n          account: user,\n          name: moduleName,\n        },\n      },\n      httpErrors: {\n        404: 'module not found',\n      },\n    })\n\n    // TODO: set followRedirect to false and intercept 302 redirects\n    const location = res.redirectUrls[0].toString()\n    if (!location) {\n      throw new NotFound({ prettyMessage: 'module not found' })\n    }\n    const version = location.match(`${moduleName}-(.+).opm`)[1]\n    if (!version) {\n      throw new InvalidResponse({ prettyMessage: 'version invalid' })\n    }\n    return version\n  }\n\n  async handle({ user, moduleName }) {\n    const version = await this.fetch({ user, moduleName })\n\n    return renderVersionBadge({ version })\n  }\n}\n","sourceCodeStart":34,"sourceCodeEnd":67,"githubUrl":"https://github.com/badges/shields/blob/766fd8bc89a90b8534dc573ab72dec30215ab1ec/services/opm/opm-version.service.js#L34-L67","documentation":"The OPM (OpenResty Package Manager) version service issues a request expecting the server to respond with a 302 redirect whose Location URL ends in `<moduleName>-<version>.opm`. If there is no redirect location (`res.redirectUrls[0]` is empty), it throws NotFound — meaning the module/user path did not resolve to a downloadable module on luarocks/opm.","triggerScenarios":"Calling the OPM version badge with a user/moduleName combination for which the opm server issues no redirect: nonexistent module, wrong user namespace, or the server responding 200 without redirecting.","commonSituations":"Modules removed from opm/luarocks.org; misspelled rock names (hyphen vs underscore); API changes on opm server causing it to stop redirecting (the code even notes a TODO around redirect handling).","solutions":["Verify the module name and user namespace on the opm/luarocks site and correct the badge URL.","Check whether the module still exists upstream; republish or pick a maintained alternative.","Manually curl -I the opm module URL to see if a 302 Location header is returned; if the server behavior changed, the service may need updating.","Use the exact rock name including correct hyphenation."],"exampleFix":"// before\nGET /opm/v/bungle/lua-resty-template-missing.json\n// after\nGET /opm/v/bungle/lua-resty-template.json","handlingStrategy":"validation","validationCode":"// Confirm the opm module resolves with a redirect before requesting the badge\nconst res = await fetch(`https://opm.openresty.org/api/pkg/individual/${user}/${moduleName}`, { redirect: 'manual' })\nif (res.status !== 302 || !res.headers.get('location')) {\n  throw new Error(`OPM module ${user}/${moduleName} not found`)\n}","typeGuard":"function hasRedirect(res) {\n  return res.redirectUrls && res.redirectUrls.length > 0 &&\n    Boolean(res.redirectUrls[0])\n}","tryCatchPattern":"try {\n  const version = await getOpmVersion(user, moduleName)\n} catch (e) {\n  if (e.message === 'module not found') {\n    // show fallback badge or remove it from the README\n  } else { throw e }\n}","preventionTips":["Verify the rock exists on opm.openresty.org before adding the badge","Use the exact published module name including hyphenation","Periodically re-check badges for removed upstream modules"],"tags":["http","redirect","not-found","opm","third-party-api"],"backgroundTag":"upstream-resource-not-found","analyzedSha":"766fd8bc89a90b8534dc573ab72dec30215ab1ec","analyzedAt":"2026-08-30T01:40:27.499Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}