{"record":{"id":"4ee0d28d1650277a","repo":"hashicorp/consul","slug":"unable-to-locate-value-class","errorCode":null,"errorMessage":"Unable to locate '${value.class}'","messagePattern":"Unable to locate '(.+?)'","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ui/packages/consul-ui/app/instance-initializers/container.js","lineNumber":29,"sourceCode":"\nexport const services = assign.all(\n  [...doc.querySelectorAll(`script[data-services]`)].map(($item) =>\n    JSON.parse($item.dataset[`services`])\n  )\n);\n\nconst inject = function (container, obj) {\n  // inject all the things\n  Object.entries(obj).forEach(([key, value]) => {\n    switch (true) {\n      case typeof value.class === 'string':\n        if (require.has(value.class)) {\n          container.register(\n            key.replace('auth-provider:', 'torii-provider:'),\n            require(value.class).default\n          );\n        } else {\n          throw new Error(`Unable to locate '${value.class}'`);\n        }\n        break;\n    }\n  });\n};\nexport default {\n  name: 'container',\n  initialize(application) {\n    inject(application, services);\n\n    const container = application.lookup('service:container');\n    // find all the services and add their classes to the container so we can\n    // look instances up by class afterwards as we then resolve the\n    // registration for each of these further down this means that any top\n    // level code for these services is executed, this is most useful for\n    // making sure any annotation type decorators are executed.\n    // For now we only want repositories, so only look for those for the moment\n    let repositories = container","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/hashicorp/consul/blob/2397ff0d763d34f2fe37fe59fde6a7f7fc430a3e/ui/packages/consul-ui/app/instance-initializers/container.js#L11-L47","documentation":"Thrown during consul-ui boot by the 'container' instance initializer. It reads service registrations from <script data-services> tags embedded in the served HTML and, for every entry whose 'class' is a string, resolves that Ember module id with require.has(). The error means the configured module id (typically an auth-provider class) is not present in the application bundle the browser actually loaded.","triggerScenarios":"A data-services payload entry like {\"class\":\"some/module-id\"} where 'some/module-id' is not resolvable by Ember's require(): module missing from the build (addon not installed or tree-shaken), module renamed/moved after an upgrade, a typo in the configured class path, or HTML generated by a backend that does not match the shipped frontend build.","commonSituations":"Upgrading consul-ui or its addons where an auth provider module id changed; serving UI assets built separately from the HTML that references them; test/CI harnesses injecting a data-services payload without the corresponding modules; auth-provider config referencing a provider not compiled into the build.","solutions":["Read the error message for the exact module id, then inspect the <script data-services> payload in the served HTML to see which entry declares it","Verify the module exists in this build: search the dist assets, or run require.has('<module-id>') in the browser console","If the module belongs to an addon, ensure the addon is installed and its module survives the build (not tree-shaken or excluded via resolver config)","Align the backend that emits data-services with the frontend build that ships the module, or correct the typo in the class path","As a last resort remove or replace the entry so application boot can proceed"],"exampleFix":"// before: payload references a module id not present in the build\n<script type=\"text/plain\" data-services='{\"auth-provider:oidc\":{\"class\":\"auth-providers/oidc\"}}'></script>\n// -> Error: Unable to locate 'auth-providers/oidc'\n\n// after: point 'class' at a module id that exists in this build\n<script type=\"text/plain\" data-services='{\"auth-provider:oidc\":{\"class\":\"consul-ui/auth-providers/oidc\"}}'></script>","handlingStrategy":"validation","validationCode":"// run before app boot, on the same payload the initializer will consume\nimport require from 'require';\n\nexport function unresolvableClasses(services) {\n  return Object.entries(services)\n    .filter(([, v]) => typeof v?.class === 'string')\n    .filter(([, v]) => !require.has(v.class))\n    .map(([key, v]) => `${key} -> ${v.class}`);\n}\n// const missing = unresolvableClasses(services);\n// if (missing.length) { console.error('unresolvable service classes', missing); }","typeGuard":"const isResolvableServiceEntry = (v) =>\n  v != null && typeof v.class === 'string' && require.has(v.class);","tryCatchPattern":"try {\n  await app.boot();\n} catch (e) {\n  if (e instanceof Error && /Unable to locate/.test(e.message)) {\n    // e.message contains the exact missing module id; compare it against\n    // the data-services payload to find the misconfigured entry\n    reportBootError(e.message, document.querySelectorAll('script[data-services]'));\n  }\n  throw e;\n}","preventionTips":["Treat the data-services class paths as a contract between backend HTML and the UI build; assert them in an integration test","Keep auth-provider addons pinned and re-run UI build checks after upgrades","Never hand-edit the data-services payload to reference modules that are not exported by the build"],"tags":["ember","consul-ui","dependency-injection","config","boot"],"backgroundTag":null,"analyzedSha":"2397ff0d763d34f2fe37fe59fde6a7f7fc430a3e","analyzedAt":"2026-08-15T19:19:47.700Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}