emberjs/ember.js · error · Error

Attempted to resolve `${value}`, which was expected to be a

Error message

Attempted to resolve `${value}`, which was expected to be a component, but nothing was found.

What it means

In a DEBUG build with a resolver, createCurryRef attempts resolver.lookupComponent for a string-based curried component definition. If the resolver returns nothing, it throws this error: the named component does not exist under the given owner/resolver.

Source

Thrown at packages/@glimmer/runtime/lib/references/curry-value.ts:56

    } 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);
    } else if (isIndexable(value)) {
      curriedDefinition = curry(type, value, owner, args);
    } else {
      curriedDefinition = null;
    }

    lastValue = value;

    return curriedDefinition;
  });
}

View on GitHub (pinned to 26f97246a8)

Solutions

  1. Verify the component exists at the expected path (e.g. app/components/foo-bar.js|gjs|hbs) and the string matches its dasherized name exactly.
  2. Import the component directly and pass the definition instead of a string.
  3. Log/print the computed name at runtime to catch dynamically built names with typos.
  4. Confirm the owner/app instance the resolver uses actually contains the component (addon mounted correctly).

Example fix

// before
this.kind = 'catridge-card'; // typo
<Card @body={{component this.kind}} />

// after
this.kind = 'cartridge-card';
// or better, in strict mode:
import CartridgeCard from './cartridge-card';
<Card @body={{CartridgeCard}} />
Defensive patterns

Strategy: validation

Validate before calling

function assertComponentResolves(resolver, name, owner) {
  const def = resolver.lookupComponent?.(name, owner);
  if (!def) throw new Error(`Component '${name}' not found — check spelling/registration`);
  return def;
}

Prevention

When it happens

Trigger: Passing a string component name to `{{component ...}}` in a resolver-based (loose-mode) template where no component with that name/dasherized path is registered, e.g. a typo like `{{component "foo-barr"}}` or the component lives in a different namespace the resolver can't see.

Common situations: Component renamed or moved so the resolver lookup misses; dynamically computed names with typos; pod/module structure changes (e.g. after Embroider migration) breaking resolution.

Related errors


AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01). Data as JSON: /api/errors/7eff6e3a859effa4. Report an issue: GitHub.