{"record":{"id":"5475648146ad84db","repo":"emberjs/ember.js","slug":"custom-component-managers-must-have-a-capabilitie","errorCode":null,"errorMessage":"Custom component managers must have a `capabilities` property that is the result of calling the `capabilities('3.13')` (imported via `import { capabilities } from '@ember/component';`). Received: `${JSON.stringify(delegate.capabilities)}` for: `${delegate}`","messagePattern":"Custom component managers must have a `capabilities` property that is the result of calling the `capabilities\\('3\\.13'\\)` \\(imported via `import (.+?) from '@ember/component';`\\)\\. Received: `(.+?)` for: `(.+?)`","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@glimmer/manager/lib/public/component.ts","lineNumber":129,"sourceCode":"  O extends Owner,\n  ComponentInstance,\n> implements InternalComponentManager<CustomComponentState<ComponentInstance>> {\n  private componentManagerDelegates = new WeakMap<O, ComponentManager<ComponentInstance>>();\n\n  constructor(private factory: ManagerFactory<O, ComponentManager<ComponentInstance>>) {}\n\n  private getDelegateFor(owner: O) {\n    let { componentManagerDelegates } = this;\n    let delegate = componentManagerDelegates.get(owner);\n\n    if (delegate === undefined) {\n      let { factory } = this;\n      delegate = factory(owner);\n\n      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- @fixme\n      if (DEBUG && !FROM_CAPABILITIES!.has(delegate.capabilities)) {\n        // TODO: This error message should make sense in both Ember and Glimmer https://github.com/glimmerjs/glimmer-vm/issues/1200\n        throw new Error(\n          `Custom component managers must have a \\`capabilities\\` property that is the result of calling the \\`capabilities('3.13')\\` (imported via \\`import { capabilities } from '@ember/component';\\`). Received: \\`${JSON.stringify(\n            delegate.capabilities\n            // eslint-disable-next-line @typescript-eslint/no-base-to-string\n          )}\\` for: \\`${delegate}\\``\n        );\n      }\n\n      componentManagerDelegates.set(owner, delegate);\n    }\n\n    return delegate;\n  }\n\n  create(\n    owner: O,\n    definition: ComponentDefinitionState,\n    vmArgs: VMArguments\n  ): CustomComponentState<ComponentInstance> {","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/emberjs/ember.js/blob/26f97246a8bf2e28edf26ac3093da2e86c04ffc5/packages/@glimmer/manager/lib/public/component.ts#L111-L147","documentation":"When a component definition is first used, `getDelegateFor` instantiates the custom component manager and verifies its `capabilities` property was produced by the real `capabilities('3.13')` function (tracked via an internal FROM_CAPABILITIES set). A manager whose capabilities object was hand-built, faked, or produced by a different copy of the library fails this check and throws, including a JSON dump of what was received.","triggerScenarios":"A component manager class whose `capabilities` is a plain object literal `{ asyncLifeCycleCallbacks: true, ... }` instead of the result of `capabilities('3.13')`; or `capabilities` imported from a duplicate/mismatched copy of @glimmer/manager so the token check fails.","commonSituations":"Mocking capabilities in tests with plain objects; duplicated @glimmer/manager versions in node_modules; managers written against old Glimmer versions before capabilities tokens existed.","solutions":["Set `static capabilities = capabilities('3.13')` on the manager class using the real import from @glimmer/manager (or Ember's @ember/component re-export)","Never hand-construct a capabilities-shaped object literal","Deduplicate @glimmer/manager so the manager and the capabilities producer share one module instance","Inspect the JSON in the error to confirm whether capabilities is undefined (missing property) or a fake object"],"exampleFix":"// before\nclass MyManager {\n  capabilities = { asyncLifeCycleCallbacks: true, createInstance: true };\n}\n// after\nimport { capabilities } from '@ember/component'; // or @glimmer/manager\nclass MyManager {\n  capabilities = capabilities('3.13', { asyncLifeCycleCallbacks: true, createInstance: true });\n}","handlingStrategy":"validation","validationCode":"import { capabilities } from '@ember/component';\nclass MyManager {\n  static create(attrs) { return new this(attrs); }\n  capabilities = capabilities('3.13', { asyncLifecycleCallbacks: true, createInstance: true, updateHook: true });\n}\n// verify before use:\nconsole.assert(typeof MyManager.prototype.capabilities === 'object');","typeGuard":"function hasRealCapabilities(m: unknown): m is { capabilities: ComponentCapabilities } { return m !== null && typeof m === 'object' && m.capabilities instanceof Object && Object.isFrozen(m.capabilities); }","tryCatchPattern":"try { owner.factoryFor('component:x').create(); } catch (e) { if (/must have a `capabilities` property/.test(e.message)) { console.error('Manager capabilities not built by capabilities(); check for duplicate @glimmer/manager copies'); } throw e; }","preventionTips":["Only assign capabilities from the real capabilities() function, never object literals","Deduplicate @glimmer/manager across dependencies","Render each custom component in a smoke test"],"tags":["component-manager","capabilities","registration"],"backgroundTag":"invalid-manager-capabilities-token","analyzedSha":"26f97246a8bf2e28edf26ac3093da2e86c04ffc5","analyzedAt":"2026-09-01T05:01:28.182Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}