{"record":{"id":"586c47c0b76d9b47","repo":"nopSolutions/nopCommerce","slug":"aggregated-error-summaries","errorCode":null,"errorMessage":"{aggregated error summaries}","messagePattern":"\\{aggregated error summaries\\}","errorType":"exception","errorClass":"NopException","httpStatus":null,"severity":"error","filePath":"src/Plugins/Nop.Plugin.Tax.Avalara/Services/AvalaraTaxManager.cs","lineNumber":239,"sourceCode":"\n    /// <summary>\n    /// Create tax transaction\n    /// </summary>\n    /// <param name=\"model\">Transaction details</param>\n    /// <returns>Created transaction</returns>\n    protected TransactionModel CreateTransaction(CreateTransactionModel model)\n    {\n        var transaction = ServiceClient.CreateTransaction(null, model)\n            ?? throw new NopException(\"No response from the service\");\n\n        //whether there are any errors\n        var errors = transaction.messages?.Where(m => !m.severity?.ToLower().Equals(\"success\") ?? true).ToList() ?? [];\n\n        if (!errors.Any())\n            return transaction;\n\n        var message = errors.Aggregate(string.Empty, (error, message) => $\"{error}{message.summary}{Environment.NewLine}\");\n        throw new NopException(message);\n    }\n\n    /// <summary>\n    /// Prepare model to create a tax transaction\n    /// </summary>\n    /// <param name=\"address\">Tax address</param>\n    /// <param name=\"customerCode\">Customer code</param>\n    /// <param name=\"documentType\">Transaction document type</param>\n    /// <returns>\n    /// A task that represents the asynchronous operation\n    /// The task result contains the model\n    /// </returns>\n    protected async Task<CreateTransactionModel> PrepareTransactionModelAsync(Address address, string customerCode, DocumentType documentType)\n    {\n        var model = new CreateTransactionModel\n        {\n            customerCode = CommonHelper.EnsureMaximumLength(customerCode, 50),\n            date = DateTime.UtcNow,","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Plugins/Nop.Plugin.Tax.Avalara/Services/AvalaraTaxManager.cs#L221-L257","documentation":"CreateTransaction received a TransactionModel, but its messages array contained entries whose severity is not \"success\". Avalara returns non-fatal messages alongside a transaction; the plugin aggregates every non-success message.summary into one string and throws so the merchant sees all of them at once. Unlike a null response, the call technically succeeded but Avalara flagged issues.","triggerScenarios":"Avalara returns messages with severity \"Warning\" or \"Error\" (e.g., address validation warnings, tax code auto-overrides, jurisdiction guesses, or missing-nexus notices). Any single non-success severity triggers the aggregate throw, even when tax was computed.","commonSituations":"Shipping address that fails validation but is still taxable; tax code mapped to an inactive or replaced Avalara code; Nexus not fully configured so Avalara guesses the jurisdiction; cross-border transactions lacking exemption certificate handling; PCard or entity-use-code mismatches.","solutions":["Read the aggregated message text - it names the exact issue (address, tax code, nexus, jurisdiction).","Fix the specific Avalara-side condition: add Nexus for the state, correct the tax code mapping, or validate the address.","If the warnings are acceptable for your workflow, review address-validation strictness and tax-code mappings in the plugin settings.","Verify each transaction line's taxCode, itemCode, amount, and quantity match Avalara's expectations."],"exampleFix":"// before\nvar message = errors.Aggregate(string.Empty, (error, message) => $\"{error}{message.summary}{Environment.NewLine}\");\nthrow new NopException(message);\n\n// after - group by severity for actionable detail\nvar grouped = errors.GroupBy(m => m.severity?.ToLower() ?? \"unknown\");\nvar detail = string.Join(Environment.NewLine, grouped.Select(g => $\"[{g.Key}] {string.Join(\"; \", g.Select(m => m.summary))}\"));\nthrow new NopException($\"Avalara returned {errors.Count} non-success message(s):{Environment.NewLine}{detail}\");","handlingStrategy":"try-catch","validationCode":"// Nothing to validate up front - Avalara returns the messages at runtime.\n// Pre-validate address/tax-code mappings to reduce warnings:\nvar addressOk = !string.IsNullOrEmpty(addr?.postalCode) ||\n    (!string.IsNullOrEmpty(addr?.line1) && !string.IsNullOrEmpty(addr?.city) && !string.IsNullOrEmpty(addr?.region));","typeGuard":null,"tryCatchPattern":"// Distinguish aggregated-message failures from hard errors so the UI can show Avalara's text\ntry\n{\n    var tx = CreateTransaction(model);\n}\ncatch (NopException ex) when (ex.Message.Contains(\"summary\") || ex.Message.Contains(\"Avalara returned\"))\n{\n    // Avalara business messages - log as warning, surface summary to the merchant\n    await _logger.WarningAsync($\"Avalara transaction warnings: {ex.Message}\");\n    throw;\n}","preventionTips":["Keep tax-code mappings current with Avalara's active codes to avoid auto-overwrite warnings.","Configure Nexus for every state you ship into to avoid jurisdiction-guess messages.","Validate addresses (postal code / full address) before submitting to reduce address warnings.","Log and triage recurring message summaries - they flag stale configuration."],"tags":["avalara","tax-calculation","messages","validation"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}