emberjs/ember.js · error · Error
Attempted to resolve a dynamic component with a string defin
Error message
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. What it means
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.
Source
Thrown at packages/@glimmer/runtime/lib/references/curry-value.ts:44
) {
let lastValue: Maybe<Dict> | string, curriedDefinition: object | string | null;
return createComputeRef(() => {
let value = valueForRef(inner) as Maybe<Dict> | string;
if (value === lastValue) {
return curriedDefinition;
}
if (isCurriedType(value, type)) {
curriedDefinition = args ? curry(type, value, owner, args) : args;
} else if (type === CURRIED_COMPONENT && typeof value === 'string' && value) {
// Only components should enter this path, as helpers and modifiers do not
// support string based resolution
if (DEBUG) {
if (isStrict) {
throw new Error(
`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.`
);
}
let resolvedDefinition =
expect(
resolver,
'BUG: expected resolver for curried component definitions'
).lookupComponent?.(value, owner) ?? null;
if (!resolvedDefinition) {
throw new Error(
`Attempted to resolve \`${value}\`, which was expected to be a component, but nothing was found.`
);
}
}
curriedDefinition = curry(type, value, owner, args);View on GitHub (pinned to 26f97246a8)
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.
Example fix
// before
this.tabName = 'foo-tab';
{{component this.tabName}}
// after
import FooTab from './foo-tab';
this.tabs = { 'foo-tab': FooTab };
{{component (get this.tabs this.tabName)}} Defensive patterns
Strategy: type-guard
Validate before calling
import * as Components from './components';
function resolveStrict(name) {
const C = Components[name];
if (!C) throw new Error(`Unknown component '${name}' for strict mode`);
return C;
}
// pass definitions, never strings: {{component (resolveStrict this.name)}} Type guard
function isComponentDefinition(v) {
return typeof v === 'function' || (v != null && typeof v === 'object' && !(typeof v === 'string'));
} Prevention
- 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.
When it happens
Trigger: Passing a string like `this.componentName = 'foo-bar'` into `{{component this.componentName}}` or `{{#let (component this.name) ...}}` in a template compiled in strict mode.
Common situations: 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.
Related errors
- Attempted to resolve `${value}`, which was expected to be a
- You can only `once`, `passive` or `capture` named arguments
- You marked this listener as 'passive', meaning that you must
- Compile Error: ${template.problem} @ ${template.span.start}.
- A resolved helper cannot be passed as a named argument as th
AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01).
Data as JSON: /api/errors/d476e267f6b6f584.
Report an issue: GitHub.