{"record":{"id":"866332394cadda79","repo":"angular/angular-cli","slug":"class-name-classname-is-invalid","errorCode":null,"errorMessage":"Class name \"${className}\" is invalid.","messagePattern":"Class name \"(.+?)\" is invalid\\.","errorType":"validation","errorClass":"SchematicsException","httpStatus":null,"severity":"error","filePath":"packages/schematics/angular/utility/validation.ts","lineNumber":27,"sourceCode":"import { SchematicsException } from '@angular-devkit/schematics';\n\n// Must start with a letter, and must contain only alphanumeric characters or dashes.\n// When adding a dash the segment after the dash must also start with a letter.\nexport const htmlSelectorRe: RegExp =\n  /^[a-zA-Z][.0-9a-zA-Z]*((:?-[0-9]+)*|(:?-[a-zA-Z][.0-9a-zA-Z]*(:?-[0-9]+)*)*)$/;\n\n// See: https://github.com/tc39/proposal-regexp-unicode-property-escapes/blob/fe6d07fad74cd0192d154966baa1e95e7cda78a1/README.md#other-examples\nconst ecmaIdentifierNameRegExp = /^(?:[$_\\p{ID_Start}])(?:[$_\\u200C\\u200D\\p{ID_Continue}])*$/u;\n\nexport function validateHtmlSelector(selector: string): void {\n  if (selector && !htmlSelectorRe.test(selector)) {\n    throw new SchematicsException(`Selector \"${selector}\" is invalid.`);\n  }\n}\n\nexport function validateClassName(className: string): void {\n  if (!ecmaIdentifierNameRegExp.test(className)) {\n    throw new SchematicsException(`Class name \"${className}\" is invalid.`);\n  }\n}\n","sourceCodeStart":9,"sourceCodeEnd":30,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/schematics/angular/utility/validation.ts#L9-L30","documentation":"validateClassName rejects class names that are not valid ECMAScript identifiers before generating components, directives, modules, pipes, services, or file-based schematics. It tests the derived class name against ecmaIdentifierNameRegExp, which enforces ID_Start/ID_Continue unicode property escapes, so the generated TypeScript file would otherwise not compile.","triggerScenarios":"Running `ng generate component|directive|module|pipe|service` (or generateFromFiles) with a --name that yields an invalid identifier: leading digits, hyphens, spaces, symbols like 'my-component' or '2fa-service' that cannot become a valid TS class name.","commonSituations":"Passing kebab-case names with special characters expecting auto-conversion, starting names with a number, names containing slashes or spaces, or non-ASCII names rejected by the strict unicode identifier regex.","solutions":["Rename the schematic input to a valid identifier: letters, $, _ first, then letters/digits/$/_, e.g. user-profile becomes UserProfile internally — use `ng generate service user-profile` without extra symbols.","Remove leading digits or punctuation from the name, e.g. 2fa-auth -> two-factor-auth.","Quote and escape nothing: pass a plain name and let the CLI derive the class name; avoid paths with stray characters.","Generate with a valid name and manually rename the exported class afterwards if a non-standard name is required."],"exampleFix":"// before\nng generate service 2fa-auth\n// after\nng generate service two-factor-auth","handlingStrategy":"validation","validationCode":"const ecmaIdentifierNameRegExp = /^(?:[$_\\p{ID_Start}])(?:[$_\\u200C\\u200D\\p{ID_Continue}])*$/u;\nconst className = name.replace(/-([a-z])/g, (_, c) => c.toUpperCase()).replace(/^[0-9]/, '_');\nif (!ecmaIdentifierNameRegExp.test(className)) {\n  throw new Error(`Name \"${name}\" cannot produce a valid TS class name`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use kebab-case names starting with a letter (e.g. user-profile, not 2fa-auth).","Avoid symbols, spaces, and non-ASCII characters in schematic names.","Let the CLI derive class names; only pass names you would accept as a JavaScript identifier after camelCasing."],"tags":["schematics","validation","typescript"],"backgroundTag":"invalid-identifier-name","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}