{"record":{"id":"3292cd9a42992083","repo":"nopSolutions/nopCommerce","slug":"unsupported-file-avalarataxdefaults-taxratesfilep","errorCode":null,"errorMessage":"Unsupported file {AvalaraTaxDefaults.TaxRatesFilePath} structure","messagePattern":"Unsupported file (.+?) structure","errorType":"exception","errorClass":"NopException","httpStatus":null,"severity":"warning","filePath":"src/Plugins/Nop.Plugin.Tax.Avalara/Services/AvalaraTaxManager.cs","lineNumber":677,"sourceCode":"    /// </returns>\n    protected async Task<List<TaxRate>> GetTaxRatesFromFileAsync()\n    {\n        //try to create file if doesn't exist\n        var filePath = _fileProvider.MapPath(AvalaraTaxDefaults.TaxRatesFilePath);\n        if (!_fileProvider.FileExists(filePath))\n            await DownloadTaxRatesAsync();\n\n        if (!_fileProvider.FileExists(filePath))\n            throw new NopException($\"File {AvalaraTaxDefaults.TaxRatesFilePath} not found\");\n\n        //get file lines\n        var text = await _fileProvider.ReadAllTextAsync(filePath, Encoding.UTF8);\n        if (string.IsNullOrEmpty(text))\n            throw new NopException($\"File {AvalaraTaxDefaults.TaxRatesFilePath} is empty\");\n\n        var lines = text.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries);\n        if (!lines.Any() || lines[0].Split(',').Length < 14)\n            throw new NopException($\"Unsupported file {AvalaraTaxDefaults.TaxRatesFilePath} structure\");\n\n        //prepare tax rates\n        var taxRates = lines.Skip(1).Select(line =>\n        {\n            try\n            {\n                var values = line.Split(',', StringSplitOptions.TrimEntries);\n                return new TaxRate\n                {\n                    Zip = values[0], //ZIP_CODE\n                    State = values[1], //STATE_ABBREV\n                    County = values[2], //COUNTY_NAME\n                    City = values[3], //CITY_NAME\n                    StateTax = decimal.Parse(values[4], NumberStyles.Any, CultureInfo.InvariantCulture), //STATE_SALES_TAX\n                    CountyTax = decimal.Parse(values[6], NumberStyles.Any, CultureInfo.InvariantCulture), //COUNTY_SALES_TAX\n                    CityTax = decimal.Parse(values[8], NumberStyles.Any, CultureInfo.InvariantCulture), //CITY_SALES_TAX\n                    TotalTax = decimal.Parse(values[10], NumberStyles.Any, CultureInfo.InvariantCulture), //TOTAL_SALES_TAX\n                    ShippingTaxable = string.Equals(values[11], \"y\", StringComparison.InvariantCultureIgnoreCase), //TAX_SHIPPING_ALONE","sourceCodeStart":659,"sourceCodeEnd":695,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Plugins/Nop.Plugin.Tax.Avalara/Services/AvalaraTaxManager.cs#L659-L695","documentation":"The fallback CSV's first line (header) splits into fewer than 14 comma-separated columns, so the parser does not recognize the schema. The expected layout has ZIP_CODE, STATE_ABBREV, COUNTY_NAME, plus rate columns; fewer than 14 columns means the file is the wrong format.","triggerScenarios":"The downloaded file is a different format or version than expected, or a non-CSV payload (e.g., an HTML error page) was saved with the .csv extension, so the header line yields too few columns.","commonSituations":"Avalara changed the rate-file schema; an error page got saved as the rates file; a locale using a different list separator; a partial download that truncated columns; an older plugin version against a newer file.","solutions":["Open the file and inspect the header row to confirm what was actually downloaded.","Delete the malformed file and re-download to obtain the current schema.","Verify the plugin version matches the current Avalara rate-file format; upgrade if schema changed.","If the schema legitimately changed, update the parser column indices."],"exampleFix":"// before\nif (!lines.Any() || lines[0].Split(',').Length < 14)\n    throw new NopException($\"Unsupported file {AvalaraTaxDefaults.TaxRatesFilePath} structure\");\n\n// after - report what was found vs expected\nvar headerColumns = lines.ElementAtOrDefault(0)?.Split(',').Length ?? 0;\nif (!lines.Any() || headerColumns < 14)\n    throw new NopException($\"Unsupported structure in {AvalaraTaxDefaults.TaxRatesFilePath}: expected >= 14 columns, found {headerColumns}. Re-download the file or update the plugin.\");","handlingStrategy":"validation","validationCode":"// Sanity-check the header before parsing\nvar firstLine = (await _fileProvider.ReadAllTextAsync(filePath, Encoding.UTF8))\n    ?.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();\nif (firstLine is null || firstLine.Split(',').Length < 14)\n    throw new NopException($\"Unsupported rates-file structure in {AvalaraTaxDefaults.TaxRatesFilePath}\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Inspect the rates-file header after each download to catch schema drift.","Keep the plugin version aligned with the current Avalara rate-file format.","Delete and re-download when the header column count looks wrong.","Never hand-edit the rates file into an incompatible shape."],"tags":["avalara","tax-rates","csv","parsing"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}