dotnet/efcore · error · ArgumentException
The context class name '{contextClassName}' is not a valid C
Error message
The context class name '{contextClassName}' is not a valid C# Identifier. What it means
Thrown in ReverseEngineerScaffolder.ScaffoldModel (line 77, resource ContextClassNotValidCSharpIdentifier) when the supplied context name is not a valid C# identifier or is a C# keyword. EF must emit a class with that name, so it validates via IsValidIdentifier and IsCSharpKeyword; failing either throws ArgumentException before any database work. Only checked when ContextName is non-blank.
Source
Thrown at src/EFCore.Design/Scaffolding/Internal/ReverseEngineerScaffolder.cs:77
private IModelCodeGeneratorSelector ModelCodeGeneratorSelector { get; }
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual ScaffoldedModel ScaffoldModel(
string connectionString,
DatabaseModelFactoryOptions databaseOptions,
ModelReverseEngineerOptions modelOptions,
ModelCodeGenerationOptions codeOptions)
{
if (!string.IsNullOrWhiteSpace(codeOptions.ContextName)
&& (!_cSharpUtilities.IsValidIdentifier(codeOptions.ContextName)
|| _cSharpUtilities.IsCSharpKeyword(codeOptions.ContextName)))
{
throw new ArgumentException(
DesignStrings.ContextClassNotValidCSharpIdentifier(codeOptions.ContextName));
}
var resolvedConnectionString = _connectionStringResolver.ResolveConnectionString(connectionString);
if (resolvedConnectionString != connectionString)
{
codeOptions.SuppressConnectionStringWarning = true;
}
else if (!codeOptions.SuppressOnConfiguring)
{
_reporter.WriteWarning(DesignStrings.SensitiveInformationWarning);
}
codeOptions.ConnectionString ??= connectionString;
var databaseModel = _databaseModelFactory.Create(resolvedConnectionString, databaseOptions);
var modelConnectionString = (string?)databaseModel[ScaffoldingAnnotationNames.ConnectionString];
if (!string.IsNullOrEmpty(modelConnectionString))View on GitHub (pinned to dbf9771522)
Solutions
- Choose a context name composed of letters/digits/underscores that starts with a letter or underscore (e.g. 'ShopContext').
- Avoid C# reserved keywords as the context name.
- If the name is derived programmatically, sanitize it (strip illegal chars, prefix with underscore) before passing it in.
- Leave ContextName blank to let ReverseEngineerScaffolder derive a valid default from the database name.
Example fix
// before: illegal context name dotnet ef dbcontext scaffold "..." SqlServer --context My-Context // after: valid identifier dotnet ef dbcontext scaffold "..." SqlServer --context MyContext
Defensive patterns
Strategy: validation
Validate before calling
// Validate the context name before scaffolding
var utils = new CSharpUtilities();
if (!string.IsNullOrWhiteSpace(name)
&& (!utils.IsValidIdentifier(name) || utils.IsCSharpKeyword(name)))
throw new ArgumentException($"'{name}' is not a valid C# identifier."); Type guard
static bool IsValidContextName(string name)
=> !string.IsNullOrWhiteSpace(name)
&& System.CodeDom.Compiler.CodeGenerator.IsValidLanguageIndependentIdentifier(name)
&& !CSharpKeywords.Contains(name); Try / catch
try { scaffolder.ScaffoldModel(...); }
catch (ArgumentException ex) when (ex.Message.Contains("valid C# identifier"))
{ /* sanitize the name (strip invalid chars, prefix underscore) and retry */ } Prevention
- Pass an identifier-safe context name (letters/digits/underscore, leading letter/underscore).
- Avoid C# keywords as names.
- Sanitize names derived from database/schema identifiers.
- Leave ContextName blank to use a derived default.
When it happens
Trigger: Calling ScaffoldModel (or 'dotnet ef dbcontext scaffold --context <name>') with a ContextName that contains invalid identifier characters, starts with a digit, or equals a reserved keyword. The condition `!IsValidIdentifier || IsCSharpKeyword` is true and throws ContextClassNotValidCSharpIdentifier(ContextName).
Common situations: Passing a context name with spaces, dots, hyphens, or special characters (e.g. 'My-Context', '1Context'). Using a C# keyword as the name (e.g. 'class', 'event', 'namespace'). Deriving the name from a database/schema name with illegal characters without sanitizing.
Related errors
- The property '{property}' of the argument '{argument}' canno
- Metadata model returned should not be 'null'. Provider: {pro
- Processing '{inputFile}' failed.
- You cannot add a migration with the name 'Migration'.
- The name '{migrationName}' is used by an existing migration.
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/47d6811ce0d243f8.
Report an issue: GitHub.