dotnet/efcore · error · ArgumentException
The context class name
Error message
The context class name '{contextClassName}' is not a valid C# identifier. What it means
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).
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.
Example fix
# before dotnet ef dbcontext scaffold "..." Npgsql.EntityFrameworkCore.PostgreSQL --context my-context # after dotnet ef dbcontext scaffold "..." Npgsql.EntityFrameworkCore.PostgreSQL --context MyContext
Defensive patterns
Strategy: validation
Validate before calling
if (!string.IsNullOrWhiteSpace(options.ContextName)
&& (!IsValidCSharpIdentifier(options.ContextName) || IsCSharpKeyword(options.ContextName)))
throw new ArgumentException($"'{options.ContextName}' is not a valid C# identifier.");
// helper:
static bool IsValidCSharpIdentifier(string s) =>
s.Length > 0 && (char.IsLetter(s[0]) || s[0] == '_')
&& s.All(c => char.IsLetterOrDigit(c) || c == '_'); Type guard
static bool IsValidContextName(string name) => !string.IsNullOrWhiteSpace(name) && IsValidCSharpIdentifier(name) && !IsCSharpKeyword(name);
Try / catch
try { scaffolder.ScaffoldModel(/*...*/); }
catch (ArgumentException ex) when (ex.Message.Contains("valid C# identifier"))
{ /* sanitize the name (strip invalid chars, prefix letter) and retry */ } Prevention
- 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.
When it happens
Trigger: 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'.
Common situations: 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.
Related errors
- The property ' ' of the argument ' ' cannot be 'null'.
- Metadata model returned should not be 'null'. Provider
- No files were generated in directory
- Processing ' ' failed.
- The following file(s) already exist in directory
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/f429064d06b594b6.
Report an issue: GitHub.
Appendix: 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 3a2006ef56)