angular/angular-cli · error · UnknownActionException

Unknown action: "${action.kind}".

Error message

Unknown action: "${action.kind}".

What it means

UnknownActionException is thrown by Sink.validateSingleAction when an Action has a `kind` that does not map to a known one-letter kind ('c', 'o', 'r', 'd'). This indicates a corrupted, hand-constructed, or version-incompatible Action object rather than a filesystem problem.

Source

Thrown at packages/angular_devkit/schematics/src/sink/sink.ts:116

        if (!b) {
          this._fileDoesNotExistException(action.path);
        }
      }),
    );
  }

  validateSingleAction(action: Action): Observable<void> {
    switch (action.kind) {
      case 'o':
        return this._validateOverwriteAction(action);
      case 'c':
        return this._validateCreateAction(action);
      case 'r':
        return this._validateRenameAction(action);
      case 'd':
        return this._validateDeleteAction(action);
      default:
        throw new UnknownActionException(action);
    }
  }

  commitSingleAction(action: Action): Observable<void> {
    return concat(
      this.validateSingleAction(action),
      new Observable<void>((observer) => {
        let committed: Observable<void> | null = null;
        switch (action.kind) {
          case 'o':
            committed = this._overwriteFile(action.path, action.content);
            break;
          case 'c':
            committed = this._createFile(action.path, action.content);
            break;
          case 'r':
            committed = this._renameFile(action.path, action.to);
            break;

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Only construct actions via the official Action classes (CreateFileAction, OverwriteFileAction, RenameFileAction, DeleteFileAction).
  2. Fix the `kind` value to one of 'c', 'o', 'r', 'd'.
  3. Regenerate/re-record the action list with a matching version of @angular-devkit/schematics instead of replaying stale serialized actions.

Example fix

// before
sink.commitSingleAction({ kind: 'create', path, content } as any);
// after
import { CreateFileAction } from '@angular-devkit/schematics/src/tree/action';
sink.commitSingleAction(new CreateFileAction(path, content));
Defensive patterns

Strategy: validation

Validate before calling

const VALID_KINDS = ['c', 'o', 'r', 'd'];
if (!VALID_KINDS.includes(action.kind)) throw new Error(`Bad action kind: ${action.kind}`);

Type guard

function isValidKind(k: unknown): k is 'c' | 'o' | 'r' | 'd' {
  return k === 'c' || k === 'o' || k === 'r' || k === 'd';
}

Try / catch

try { sink.commitSingleAction(action); } catch (e) { if (e instanceof UnknownActionException) { logger.error(`Unrecognized action: ${JSON.stringify(action)}`); } else { throw e; } }

Prevention

When it happens

Trigger: Passing a custom/hand-made object { kind: 'x', ... } to sink.commitSingleAction(), or deserializing actions from an incompatible schema/version where kind values changed.

Common situations: Custom tooling that records and replays action lists across versions of @angular-devkit/schematics; typos when constructing actions programmatically; corrupted persisted commit queues.

Related errors


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