{"record":{"id":"b707d3428485d587","repo":"nopSolutions/nopCommerce","slug":"admin-configuration-emailaccounts-fields-clientid","errorCode":null,"errorMessage":"Admin.Configuration.EmailAccounts.Fields.ClientId.Required","messagePattern":"Admin\\.Configuration\\.EmailAccounts\\.Fields\\.ClientId\\.Required","errorType":"exception","errorClass":"NopException","httpStatus":null,"severity":"error","filePath":"src/Libraries/Nop.Services/Messages/SmtpBuilder.cs","lineNumber":53,"sourceCode":"        ILocalizationService localizationService,\n        INopFileProvider fileProvider)\n    {\n        _emailAccountSettings = emailAccountSettings;\n        _emailAccountService = emailAccountService;\n        _localizationService = localizationService;\n        _fileProvider = fileProvider;\n    }\n\n    #endregion\n\n    #region Utilities\n\n    protected virtual async Task<SaslMechanism> GetGmailCredentialsAsync(EmailAccount emailAccount)\n    {\n        ArgumentNullException.ThrowIfNull(emailAccount);\n\n        if (string.IsNullOrEmpty(emailAccount.ClientId))\n            throw new NopException(await _localizationService.GetResourceAsync(\"Admin.Configuration.EmailAccounts.Fields.ClientId.Required\"));\n\n        if (string.IsNullOrEmpty(emailAccount.ClientSecret))\n            throw new NopException(await _localizationService.GetResourceAsync(\"Admin.Configuration.EmailAccounts.Fields.ClientSecret.Required\"));\n\n        var tokenFilePath = _fileProvider.MapPath(NopMessageDefaults.GmailAuthStorePath);\n        var credentialRoot = _fileProvider.Combine(tokenFilePath, emailAccount.Email);\n\n        var codeFlow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer\n        {\n            ClientSecrets = new ClientSecrets\n            {\n                ClientId = emailAccount.ClientId,\n                ClientSecret = emailAccount.ClientSecret\n            },\n            Scopes = NopMessageDefaults.GmailScopes,\n            DataStore = new FileDataStore(credentialRoot, true)\n        });\n","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Libraries/Nop.Services/Messages/SmtpBuilder.cs#L35-L71","documentation":"Thrown by SmtpBuilder.GetGmailCredentialsAsync when building Gmail OAuth2 (SASL) credentials for an EmailAccount. Gmail OAuth requires a ClientId; if EmailAccount.ClientId is empty, the OAuth flow cannot start, so it throws a NopException whose message is a localized admin resource key. This is a configuration-completeness check before contacting Google.","triggerScenarios":"An EmailAccount configured with the Gmail host/auth scheme but with a blank ClientId field; sending an email via such an account triggers GetGmailCredentialsAsync.","commonSituations":"Admin created a Gmail OAuth email account but did not paste the Google OAuth ClientId; deploying without copying OAuth credentials; switching an account to Gmail without completing the OAuth setup.","solutions":["In admin (Configuration > Email accounts), open the account and set the ClientId from the Google Cloud OAuth client.","Also set ClientSecret and complete the OAuth consent/authorization flow.","Ensure the email account's host is the Gmail SMTP host and the correct credential fields are populated.","Verify the Google Cloud project has the Gmail SMTP/SCOPE enabled."],"exampleFix":"// before - account created with empty ClientId\n\n// after - set the ClientId in admin, or validate before sending\nif (string.IsNullOrEmpty(account.ClientId) || string.IsNullOrEmpty(account.ClientSecret))\n    return Error(\"Complete Gmail OAuth credentials (ClientId + ClientSecret) for this email account.\");","handlingStrategy":"validation","validationCode":"// Validate Gmail OAuth fields before triggering an SMTP build/send\nif (account.Host.Contains(\"gmail\", StringComparison.OrdinalIgnoreCase)\n    && string.IsNullOrEmpty(account.ClientId))\n    return Error(\"Set the Gmail OAuth ClientId for this email account.\");","typeGuard":"static bool HasGmailCredentials(EmailAccount a)\n    => !string.IsNullOrEmpty(a.ClientId) && !string.IsNullOrEmpty(a.ClientSecret);","tryCatchPattern":"try { await smtpBuilder.BuildAsync(account); }\ncatch (NopException ex) when (ex.Message.Contains(\"EmailAccounts.Fields.ClientId.Required\"))\n{ /* surface a localized 'set ClientId' message to the admin */ }","preventionTips":["Complete Gmail OAuth setup (ClientId + ClientSecret + consent) before marking the account active.","Validate OAuth fields when saving the email account in admin.","Document the required Google Cloud project settings."],"tags":["email","smtp","oauth","gmail","configuration","nopcommerce"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}