angular/angular · error · FatalDiagnosticError

VALUE_HAS_WRONG_TYPE

VALUE_HAS_WRONG_TYPE

Error message

No locator specified.

What it means

All four signal query functions need a locator argument (string template reference or component/directive class) that becomes the query predicate. tryParseSignalQueryFromInitializer reads query.call.arguments[0]; when it is undefined, VALUE_HAS_WRONG_TYPE is thrown on the call node with 'No locator specified.'.

Source

Thrown at packages/compiler-cli/src/ngtsc/annotations/directive/src/query_functions.ts:95

  }

  const query = tryParseInitializerApi(
    QUERY_INITIALIZER_FNS,
    member.value,
    reflector,
    importTracker,
  );
  if (query === null) {
    return null;
  }

  validateAccessOfInitializerApiMember(query, member);

  const {functionName} = query.api;
  const isSingleQuery = functionName === 'viewChild' || functionName === 'contentChild';
  const predicateNode = query.call.arguments[0] as ts.Expression | undefined;
  if (predicateNode === undefined) {
    throw new FatalDiagnosticError(
      ErrorCode.VALUE_HAS_WRONG_TYPE,
      query.call,
      'No locator specified.',
    );
  }

  const optionsNode = query.call.arguments[1] as ts.Expression | undefined;
  if (optionsNode !== undefined && !ts.isObjectLiteralExpression(optionsNode)) {
    throw new FatalDiagnosticError(
      ErrorCode.VALUE_HAS_WRONG_TYPE,
      optionsNode,
      'Argument needs to be an object literal.',
    );
  }
  const options = optionsNode && reflectObjectLiteral(optionsNode);
  const read = options?.has('read') ? parseReadOption(options.get('read')!) : null;
  const descendants = options?.has('descendants')
    ? parseDescendantsOption(options.get('descendants')!)

View on GitHub (pinned to 51cb07e980)

Solutions

  1. Pass a locator: viewChild('panel') for a template reference, or viewChild(PanelComponent) for a component/directive class
  2. For token-based locators use the read option on a class locator rather than omitting the argument

Example fix

// before
export class Accordion {
  header = viewChild();
}

// after
export class Accordion {
  header = viewChild('header');  // or viewChild(PanelHeader) for a class locator
}
Defensive patterns

Strategy: validation

Validate before calling

const noLocator = /\w+\s*=\s*(viewChild|contentChild|viewChildren|contentChildren)\s*\(\s*\)/;
if (noLocator.test(src)) fail('signal query called without a locator argument');

Prevention

When it happens

Trigger: panel = viewChild(); items = viewChildren(); tab = contentChild(); tabs = contentChildren(); - any zero-argument call of these initializer functions.

Common situations: Refactoring from constructor queries and dropping the argument mid-edit; relying on TypeScript's 'expected 1 argument' error being suppressed (JS files, satisfy hacks, generated code); IDE stub completions that insert empty calls.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of angular/angular@51cb07e980 (2026-08-22). Data as JSON: /api/errors/824b8f2453337e6a. Report an issue: GitHub.