angular/angular-cli · error · OptionIsNotDefinedException

Option "${match}" is not defined.

Error message

Option "${match}" is not defined.

What it means

In applyPathTemplate, when a path placeholder match (without pipe separator) resolves to undefined in the template options data, OptionIsNotDefinedException is thrown. Template Content/Substitution options must provide a value for every __name__-style placeholder.

Source

Thrown at packages/angular_devkit/schematics/src/rules/template.ts:115

    let path = entry.path as string;
    const content = entry.content;
    const original = path;

    let start = path.indexOf(is);
    // + 1 to have at least a length 1 name. `____` is not valid.
    let end = path.indexOf(ie, start + isL + 1);

    while (start != -1 && end != -1) {
      const match = path.substring(start + isL, end);
      let replacement = data[match];

      if (!options.pipeSeparator) {
        if (typeof replacement == 'function') {
          replacement = replacement.call(data, original);
        }

        if (replacement === undefined) {
          throw new OptionIsNotDefinedException(match);
        }
      } else {
        const [name, ...pipes] = match.split(options.pipeSeparator);
        replacement = data[name];

        if (typeof replacement == 'function') {
          replacement = replacement.call(data, original);
        }

        if (replacement === undefined) {
          throw new OptionIsNotDefinedException(name);
        }

        replacement = pipes.reduce((acc: string, pipe: string) => {
          if (!pipe) {
            return acc;
          }
          if (!(pipe in data)) {

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Supply the missing option: applyTemplates({ name, ... }) so every placeholder has a value.
  2. Fix placeholder/key spelling mismatches between the template path and the options object.
  3. Provide a default: applyTemplates({ name: options.name ?? 'default' }).

Example fix

// before
mergeWith(apply(source, [template({})]))
// after
mergeWith(apply(source, [template({ name: options.name })]))
Defensive patterns

Strategy: validation

Validate before calling

const placeholders = [...path.matchAll(/__([^_]+)__/g)].map(m => m[1].split('@')[0]);
const missing = placeholders.filter(k => !(k in data));
if (missing.length) throw new Error(`Missing template options: ${missing.join(', ')}`);

Type guard

function hasAllOptions(data: Record<string, unknown>, keys: string[]): data is Required<Record<string, unknown>> {
  return keys.every(k => data[k] !== undefined);
}

Try / catch

try {
  return mergeWith(apply(source, [template(options)]));
} catch (err) {
  if (err instanceof OptionIsNotDefinedException) {
    console.error('Add missing template option:', err.message);
  }
}

Prevention

When it happens

Trigger: Path like '__name@dasherize__.ts' where options/`data` lacks a 'name' key, or a replacement function returns undefined for the original value.

Common situations: Template files using placeholders not supplied by applyTemplates({...}); renaming files where the data object key is misspelled ('filename' vs 'name'); chained replacements returning undefined.

Related errors


AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30). Data as JSON: /api/errors/8f81ab5d3b1b12eb. Report an issue: GitHub.