{"record":{"id":"8beb2464bc13c1e7","repo":"nopSolutions/nopCommerce","slug":"textrequiredlocale-localized-formatted-with-la","errorCode":null,"errorMessage":"{textRequiredLocale} (localized, formatted with languageName)","messagePattern":"(.+?) \\(localized, formatted with languageName\\)","errorType":"validation","errorClass":"NopException","httpStatus":null,"severity":"warning","filePath":"src/Libraries/Nop.Services/ArtificialIntelligence/ArtificialIntelligenceService.cs","lineNumber":281,"sourceCode":"    /// <param name=\"textRequiredLocale\">Locale for raising an exception about the title field required</param>\n    /// <param name=\"titleRequiredLocale\">Locale for raising an exception about the text field required</param>\n    /// <param name=\"title\">Title for validate</param>\n    /// <param name=\"text\">Text for validate</param>\n    /// <returns>\n    /// A task that represents the asynchronous operation\n    /// The task result contains the validated title and text\n    /// </returns>\n    public virtual async Task<(string title, string text)> ValidateTitleAndTextAsync(string languageName,\n        string textRequiredLocale, string titleRequiredLocale, string title, string text)\n    {\n        if (string.IsNullOrEmpty(title))\n            throw new NopException(string.Format(await _localizationService.GetResourceAsync(titleRequiredLocale), languageName));\n\n        if (!string.IsNullOrEmpty(text))\n            text = Regex.Replace(text, \"<.*?>\", string.Empty);\n\n        if (string.IsNullOrEmpty(text))\n            throw new NopException(string.Format(await _localizationService.GetResourceAsync(textRequiredLocale), languageName));\n\n        return (title, text);\n    }\n\n    /// <summary>\n    /// Create product description by artificial intelligence\n    /// </summary>\n    /// <param name=\"productName\">Product name</param>\n    /// <param name=\"keywords\">Features and keywords</param>\n    /// <param name=\"toneOfVoice\">Tone of voice</param>\n    /// <param name=\"instruction\">Special instruction</param>\n    /// <param name=\"customToneOfVoice\">Custom tone of voice (applicable only for ToneOfVoiceType.Custom)</param>\n    /// <param name=\"languageId\">The language identifier</param>\n    /// <returns>\n    /// A task that represents the asynchronous operation\n    /// The task result contains the generated product description\n    /// </returns>\n    public virtual async Task<string> CreateProductDescriptionAsync(string productName, string keywords, ToneOfVoiceType toneOfVoice, string instruction, string customToneOfVoice = null, int languageId = 0)","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Libraries/Nop.Services/ArtificialIntelligence/ArtificialIntelligenceService.cs#L263-L299","documentation":"ValidateTitleAndTextAsync throws NopException when 'text' is null/empty AFTER stripping HTML tags via Regex.Replace(text, \"<.*?>\", string.Empty). So an entity whose description is only HTML with no text content, or genuinely empty, fails the check. The message is the localized textRequiredLocale formatted with languageName.","triggerScenarios":"AI meta/product generation where the entity's body/description is empty, or consists solely of markup/img tags that become empty after tag-stripping (e.g. '<img src=...>' with no text).","commonSituations":"A product with FullDescription containing only an image; a topic/blog post with empty body; localized description empty in the target language; description that is whitespace-only.","solutions":["Ensure the entity has meaningful text content (not only images/markup) in the target language before AI generation.","Pre-check the stripped text length client-side and warn the user to add body text.","If only media is present, add a caption/alt-derived text so the stripped value is non-empty."],"exampleFix":"// before\nvar (t,k,d) = await _aiService.CreateMetaTagsAsync(entity, languageId); // throws if body empty\n\n// after\nvar body = languageId == 0 ? entity.Description : await _localizationService.GetLocalizedAsync(entity, e => e.Description, languageId, false);\nif (string.IsNullOrWhiteSpace(Regex.Replace(body ?? string.Empty, \"<.*?>\", string.Empty)))\n    return; // ask user to add description text first","handlingStrategy":"validation","validationCode":"var body = languageId == 0\n    ? entity.Description\n    : await _localizationService.GetLocalizedAsync(entity, e => e.Description, languageId, false);\nvar stripped = Regex.Replace(body ?? string.Empty, \"<.*?>\", string.Empty);\nif (string.IsNullOrWhiteSpace(stripped))\n    // do not call AI meta generation; prompt user to add text content\n    return;","typeGuard":"static bool HasTextContent(string html)\n    => !string.IsNullOrWhiteSpace(Regex.Replace(html ?? string.Empty, \"<.*?>\", string.Empty));","tryCatchPattern":"try { await _aiService.CreateMetaTagsAsync(entity, languageId); }\ncatch (NopException ex) { /* body missing/empty — prompt user to add description text */ }","preventionTips":["Ensure the description/body has actual text (not only images/markup) before AI generation.","Validate stripped-text length client-side and warn before invoking AI.","For image-only content, require a caption or alt text."],"tags":["ai","validation","localization","html","nopcommerce"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}