bettercap/bettercap · error · Error

Component '${stringify(type)}' is not resolved: - templateU

Error message

Component '${stringify(type)}' is not resolved:
 - templateUrl: ${templateUrl}
 - styleUrls: ${styleUrls}
Did you run and wait for 'resolveComponentResources()'?

What it means

Thrown when a component's `ngComponentDef` is compiled (JIT) but its metadata still contains unresolved external resources: a `templateUrl` or `styleUrls` that were never fetched. Angular defers resource loading to `resolveComponentResources()`, which must be called and awaited before compiling components that reference external template/style files.

Source

Thrown at modules/ui/ui/vendor.js:55331

 */
function compileComponent(type, metadata) {
    var ngComponentDef = null;
    // Metadata may have resources which need to be resolved.
    maybeQueueResolutionOfComponentResources(metadata);
    Object.defineProperty(type, NG_COMPONENT_DEF, {
        get: function () {
            var compiler = getCompilerFacade();
            if (ngComponentDef === null) {
                if (componentNeedsResolution(metadata)) {
                    var error = ["Component '" + stringify(type) + "' is not resolved:"];
                    if (metadata.templateUrl) {
                        error.push(" - templateUrl: " + stringify(metadata.templateUrl));
                    }
                    if (metadata.styleUrls && metadata.styleUrls.length) {
                        error.push(" - styleUrls: " + JSON.stringify(metadata.styleUrls));
                    }
                    error.push("Did you run and wait for 'resolveComponentResources()'?");
                    throw new Error(error.join('\n'));
                }
                var meta = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"])({}, directiveMetadata(type, metadata), { template: metadata.template || '', preserveWhitespaces: metadata.preserveWhitespaces || false, styles: metadata.styles || EMPTY_ARRAY, animations: metadata.animations, viewQueries: extractQueriesMetadata(getReflect().propMetadata(type), isViewQuery), directives: new Map(), pipes: new Map(), encapsulation: metadata.encapsulation || ViewEncapsulation.Emulated, viewProviders: metadata.viewProviders || null });
                ngComponentDef = compiler.compileComponent(angularCoreEnv, "ng://" + stringify(type) + "/template.html", meta);
                // If component compilation is async, then the @NgModule annotation which declares the
                // component may execute and set an ngSelectorScope property on the component type. This
                // allows the component to patch itself with directiveDefs from the module after it
                // finishes compiling.
                if (hasSelectorScope(type)) {
                    var scopes = transitiveScopesFor(type.ngSelectorScope);
                    patchComponentDefWithScope(ngComponentDef, scopes);
                }
            }
            return ngComponentDef;
        },
        // Make the property configurable in dev mode to allow overriding in tests
        configurable: !!ngDevMode,
    });
}

View on GitHub (pinned to 8eca2820f3)

Solutions

  1. Call and await `resolveComponentResources(urlResolver)` before bootstrapping/compiling components that use templateUrl/styleUrls.
  2. Prefer inline `template`/`styles` in JIT/dynamic-compilation scenarios to avoid resource loading entirely.
  3. In tests, ensure TestBed initialization completes (await TestBed.compileComponents()) before creating components.
  4. Ensure components are only rendered after the bootstrap promise resolves, not before.

Example fix

// before
const cmp = createComponent(MyCmp);
// after
import { resolveComponentResources } from '@angular/compiler';
await resolveComponentResources(async url => (await fetch(url)).text());
const cmp = createComponent(MyCmp);
Defensive patterns

Strategy: validation

Validate before calling

if (cmp.decorators?.some(d => d.type === Component) &&
    (meta.templateUrl || meta.styleUrls?.length) &&
    !resourcesResolved) {
  throw new Error('Call and await resolveComponentResources() first');
}

Type guard

function isResolvedComponentMeta(m: { template?: string; templateUrl?: string }): m is { template: string; templateUrl?: undefined } {
  return typeof m.template === 'string' || m.templateUrl === undefined;
}

Try / catch

try {
  const def = type.ngComponentDef;
} catch (e) {
  if (e.message.includes("resolveComponentResources()")) {
    await resolveComponentResources(url => fetch(url).then(r => r.text()));
    // retry access after resolution
  } else { throw e; }
}

Prevention

When it happens

Trigger: Using @Component with `templateUrl` or `styleUrls` in a JIT environment without awaiting the promise returned by `resolveComponentResources()` (typically from '@angular/compiler' or a custom JIT bootstrap); triggering ngComponentDef access before resource resolution finished.

Common situations: JIT bootstrap in tests or JIT-compiled apps (no AOT), custom loaders (e.g. dynamic component compilation in plugins) that skip resource resolution, TestBed setups, upgrading Angular where bootstrap helpers previously handled this implicitly.

Related errors


AI-assisted analysis of bettercap/bettercap@8eca2820f3 (2026-09-02). Data as JSON: /api/errors/b5c15b171807dfbc. Report an issue: GitHub.