{"record":{"id":"d476e267f6b6f584","repo":"emberjs/ember.js","slug":"attempted-to-resolve-a-dynamic-component-with-a-st","errorCode":null,"errorMessage":"Attempted to resolve a dynamic component with a string definition, `${value}` in a strict mode template. In strict mode, using strings to resolve component definitions is prohibited. You can instead import the component definition and use it directly.","messagePattern":"Attempted to resolve a dynamic component with a string definition, `(.+?)` in a strict mode template\\. In strict mode, using strings to resolve component definitions is prohibited\\. You can instead import the component definition and use it directly\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@glimmer/runtime/lib/references/curry-value.ts","lineNumber":44,"sourceCode":") {\n  let lastValue: Maybe<Dict> | string, curriedDefinition: object | string | null;\n\n  return createComputeRef(() => {\n    let value = valueForRef(inner) as Maybe<Dict> | string;\n\n    if (value === lastValue) {\n      return curriedDefinition;\n    }\n\n    if (isCurriedType(value, type)) {\n      curriedDefinition = args ? curry(type, value, owner, args) : args;\n    } else if (type === CURRIED_COMPONENT && typeof value === 'string' && value) {\n      // Only components should enter this path, as helpers and modifiers do not\n      // support string based resolution\n\n      if (DEBUG) {\n        if (isStrict) {\n          throw new Error(\n            `Attempted to resolve a dynamic component with a string definition, \\`${value}\\` in a strict mode template. In strict mode, using strings to resolve component definitions is prohibited. You can instead import the component definition and use it directly.`\n          );\n        }\n\n        let resolvedDefinition =\n          expect(\n            resolver,\n            'BUG: expected resolver for curried component definitions'\n          ).lookupComponent?.(value, owner) ?? null;\n\n        if (!resolvedDefinition) {\n          throw new Error(\n            `Attempted to resolve \\`${value}\\`, which was expected to be a component, but nothing was found.`\n          );\n        }\n      }\n\n      curriedDefinition = curry(type, value, owner, args);","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/emberjs/ember.js/blob/26f97246a8bf2e28edf26ac3093da2e86c04ffc5/packages/@glimmer/runtime/lib/references/curry-value.ts#L26-L62","documentation":"In strict-mode Glimmer/Ember templates, dynamic component invocation (`<Component @x={{...}} />` via `{{component}}` or curried values) cannot resolve components by string name; string resolution requires a runtime resolver, which strict mode forbids. createCurryRef throws when a curried component value is a non-empty string and the template is strict.","triggerScenarios":"Passing a string like `this.componentName = 'foo-bar'` into `{{component this.componentName}}` or `{{#let (component this.name) ...}}` in a template compiled in strict mode.","commonSituations":"Migrating a classic (resolver-based) Ember app to strict-mode / template-only components / Embroider; dynamic tab or modal renderers that store component names as strings.","solutions":["Import the component directly and pass its class/definition instead of a string.","Use a lookup map in JS: a plain object keyed by name mapping to imported component definitions.","If string resolution is unavoidable, keep that template in a non-strict (resolver-based) context."],"exampleFix":"// before\nthis.tabName = 'foo-tab';\n{{component this.tabName}}\n\n// after\nimport FooTab from './foo-tab';\nthis.tabs = { 'foo-tab': FooTab };\n{{component (get this.tabs this.tabName)}}","handlingStrategy":"type-guard","validationCode":"import * as Components from './components';\nfunction resolveStrict(name) {\n  const C = Components[name];\n  if (!C) throw new Error(`Unknown component '${name}' for strict mode`);\n  return C;\n}\n// pass definitions, never strings: {{component (resolveStrict this.name)}}","typeGuard":"function isComponentDefinition(v) {\n  return typeof v === 'function' || (v != null && typeof v === 'object' && !(typeof v === 'string'));\n}","tryCatchPattern":null,"preventionTips":["In strict mode, always import components and pass the definition.","Use a JS lookup map (name -> imported component) for dynamic selection.","Enable template strict-mode linting to catch string resolutions early.","Add a type so component names map to imported classes, not strings."],"tags":["ember","glimmer","strict-mode","dynamic-components","developer-error"],"backgroundTag":"strict-mode-string-component-resolution","analyzedSha":"26f97246a8bf2e28edf26ac3093da2e86c04ffc5","analyzedAt":"2026-09-01T05:01:28.182Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}