{"record":{"id":"d7eca01c982d893f","repo":"angular/angular-cli","slug":"schematics-has-invalid-name-name","errorCode":null,"errorMessage":"Schematics has invalid name: \"${name}\".","messagePattern":"Schematics has invalid name: \"(.+?)\"\\.","errorType":"exception","errorClass":"InvalidSchematicsNameException","httpStatus":null,"severity":"error","filePath":"packages/angular_devkit/schematics/src/engine/schematic.ts","lineNumber":40,"sourceCode":"} from './interface';\n\nexport class InvalidSchematicsNameException extends BaseException {\n  constructor(name: string) {\n    super(`Schematics has invalid name: \"${name}\".`);\n  }\n}\n\nexport class SchematicImpl<CollectionT extends object, SchematicT extends object>\n  implements Schematic<CollectionT, SchematicT>\n{\n  constructor(\n    private _description: SchematicDescription<CollectionT, SchematicT>,\n    private _factory: RuleFactory<{}>,\n    private _collection: Collection<CollectionT, SchematicT>,\n    private _engine: Engine<CollectionT, SchematicT>,\n  ) {\n    if (!_description.name.match(/^[-@/_.a-zA-Z0-9]+$/)) {\n      throw new InvalidSchematicsNameException(_description.name);\n    }\n  }\n\n  get description(): SchematicDescription<CollectionT, SchematicT> {\n    return this._description;\n  }\n  get collection(): Collection<CollectionT, SchematicT> {\n    return this._collection;\n  }\n\n  call<OptionT extends object>(\n    options: OptionT,\n    host: Observable<Tree>,\n    parentContext?: Partial<TypedSchematicContext<CollectionT, SchematicT>>,\n    executionOptions?: Partial<ExecutionOptions>,\n  ): Observable<Tree> {\n    const context = this._engine.createContext(this, parentContext, executionOptions);\n","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular_devkit/schematics/src/engine/schematic.ts#L22-L58","documentation":"The Schematic constructor validates the schematic's name from its description against /^[-@/_.a-zA-Z0-9]+$/ and throws if it doesn't match. It guarantees schematic names only contain safe identifier characters. A description with an empty or malformed name is rejected at construction time.","triggerScenarios":"Instantiating a Schematic whose SchematicDescription.name contains characters outside [-@/_.a-zA-Z0-9] (spaces, unicode, empty string).","commonSituations":"Custom collection JSON where 'schematics.<name>.name' was mistyped or auto-generated with whitespace; dynamic generation of schematic descriptions injecting bad names; typos like 'my schematic' with a space.","solutions":["Fix the schematic name in the collection description JSON to match the allowed pattern.","If generating names programmatically, sanitize with name.replace(/[^-@/_.a-zA-Z0-9]/g, '-').","Verify the collection.json actually being loaded is the one you edited (paths/scope)."],"exampleFix":"// before (collection.json)\n{\"my schematic\": {\"factory\": \"./my-schematic\"}}\n// after\n{\"my-schematic\": {\"factory\": \"./my-schematic\"}}","handlingStrategy":"validation","validationCode":"const NAME_RE = /^[-@/_.a-zA-Z0-9]+$/;\nif (!NAME_RE.test(description.name)) {\n  throw new Error(`Invalid schematic name: ${description.name}`);\n}","typeGuard":"function isValidSchematicName(name: unknown): name is string {\n  return typeof name === 'string' && /^[-@/_.a-zA-Z0-9]+$/.test(name);\n}","tryCatchPattern":"try {\n  const schematic = collection.createSchematic(name);\n} catch (err) {\n  if (err instanceof InvalidSchematicsNameException) {\n    console.error(`Fix schematic name: ${err.message}`);\n  }\n}","preventionTips":["Keep schematic directory names matching the allowed pattern [-@/_.a-zA-Z0-9].","Sanitize any programmatically generated names.","Validate collection.json entries in CI with a small schema check."],"tags":["schematics","validation","naming","configuration"],"backgroundTag":"invalid-identifier-name","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}