{"record":{"id":"f429064d06b594b6","repo":"dotnet/efcore","slug":"the-context-class-name-contextclassname-is-not","errorCode":null,"errorMessage":"The context class name '{contextClassName}' is not a valid C# identifier.","messagePattern":"The context class name '(.+?)' is not a valid C# identifier\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Design/Scaffolding/Internal/ReverseEngineerScaffolder.cs","lineNumber":77,"sourceCode":"    private IModelCodeGeneratorSelector ModelCodeGeneratorSelector { get; }\n\n    /// <summary>\n    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to\n    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in\n    ///     any release. You should only use it directly in your code with extreme caution and knowing that\n    ///     doing so can result in application failures when updating to a new Entity Framework Core release.\n    /// </summary>\n    public virtual ScaffoldedModel ScaffoldModel(\n        string connectionString,\n        DatabaseModelFactoryOptions databaseOptions,\n        ModelReverseEngineerOptions modelOptions,\n        ModelCodeGenerationOptions codeOptions)\n    {\n        if (!string.IsNullOrWhiteSpace(codeOptions.ContextName)\n            && (!_cSharpUtilities.IsValidIdentifier(codeOptions.ContextName)\n                || _cSharpUtilities.IsCSharpKeyword(codeOptions.ContextName)))\n        {\n            throw new ArgumentException(\n                DesignStrings.ContextClassNotValidCSharpIdentifier(codeOptions.ContextName));\n        }\n\n        var resolvedConnectionString = _connectionStringResolver.ResolveConnectionString(connectionString);\n        if (resolvedConnectionString != connectionString)\n        {\n            codeOptions.SuppressConnectionStringWarning = true;\n        }\n        else if (!codeOptions.SuppressOnConfiguring)\n        {\n            _reporter.WriteWarning(DesignStrings.SensitiveInformationWarning);\n        }\n\n        codeOptions.ConnectionString ??= connectionString;\n\n        var databaseModel = _databaseModelFactory.Create(resolvedConnectionString, databaseOptions);\n        var modelConnectionString = (string?)databaseModel[ScaffoldingAnnotationNames.ConnectionString];\n        if (!string.IsNullOrEmpty(modelConnectionString))","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Design/Scaffolding/Internal/ReverseEngineerScaffolder.cs#L59-L95","documentation":"Thrown by ReverseEngineerScaffolder.ScaffoldModel when the supplied ContextName is present but is not a valid C# identifier or is a C# reserved keyword. The generated DbContext class name must be a legal identifier, so an invalid name is reported as ArgumentException (DesignStrings.ContextClassNotValidCSharpIdentifier).","triggerScenarios":"Calling 'dotnet ef dbcontext scaffold' (or Scaffold-DbContext, or the API directly) with a --context value that starts with a digit, contains invalid characters (dashes, spaces), or equals a C# keyword like 'class' or 'static'.","commonSituations":"Deriving the context name from a database name with dashes/underscores handled incorrectly; passing a keyword by accident; automated tooling that passes unsanitized database names as context names.","solutions":["Pass a context name that is a valid C# identifier and not a keyword (letters/underscores, does not start with a digit).","If generating from a database name, sanitize it (strip invalid chars, prefix with a letter/underscore) before use.","Omit --context to let EF derive a default valid name from the database."],"exampleFix":"# before\ndotnet ef dbcontext scaffold \"...\" Npgsql.EntityFrameworkCore.PostgreSQL --context my-context\n# after\ndotnet ef dbcontext scaffold \"...\" Npgsql.EntityFrameworkCore.PostgreSQL --context MyContext","handlingStrategy":"validation","validationCode":"if (!string.IsNullOrWhiteSpace(options.ContextName)\n    && (!IsValidCSharpIdentifier(options.ContextName) || IsCSharpKeyword(options.ContextName)))\n    throw new ArgumentException($\"'{options.ContextName}' is not a valid C# identifier.\");\n// helper:\nstatic bool IsValidCSharpIdentifier(string s) =>\n    s.Length > 0 && (char.IsLetter(s[0]) || s[0] == '_')\n    && s.All(c => char.IsLetterOrDigit(c) || c == '_');","typeGuard":"static bool IsValidContextName(string name) => !string.IsNullOrWhiteSpace(name) && IsValidCSharpIdentifier(name) && !IsCSharpKeyword(name);","tryCatchPattern":"try { scaffolder.ScaffoldModel(/*...*/); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"valid C# identifier\"))\n{ /* sanitize the name (strip invalid chars, prefix letter) and retry */ }","preventionTips":["Validate context names as C# identifiers before scaffolding.","Sanitize database-derived names (strip dashes/spaces, prefix with a letter).","Let EF derive a default name when the user does not supply one."],"tags":["scaffolding","reverse-engineering","validation","identifier","options"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}