{"record":{"id":"fb7e8ce2bacd275d","repo":"unopim/unopim","slug":"wrong-columns-number","errorCode":"wrong_columns_number","errorMessage":"wrong_columns_number","messagePattern":"wrong_columns_number","errorType":"error_code","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"packages/Webkul/DataTransfer/src/Helpers/Sources/AbstractSource.php","lineNumber":64,"sourceCode":"\n    /**\n     * Checks if current position is valid\n     */\n    public function valid(): bool\n    {\n        return $this->currentRowNumber !== -1;\n    }\n\n    /**\n     * Read next line from source\n     */\n    public function current(): array\n    {\n        $row = $this->currentRowData;\n\n        if (count($row) !== $this->totalColumns) {\n            throw_if($this->foundWrongQuoteFlag, \\InvalidArgumentException::class, AbstractImporter::ERROR_CODE_WRONG_QUOTES);\n            throw new \\InvalidArgumentException(AbstractImporter::ERROR_CODE_COLUMNS_NUMBER);\n        }\n\n        return array_combine($this->columnNames, $row);\n    }\n\n    /**\n     * Read next line from source\n     */\n    public function next(): void\n    {\n        $this->currentRowNumber++;\n\n        $row = $this->getNextRow();\n\n        if ($row === false || $row === []) {\n            $this->currentRowData = [];\n\n            $this->currentRowNumber = -1;","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/unopim/unopim/blob/c27a402253ed2bcee0f3eb16319fa7fc5eec5ffd/packages/Webkul/DataTransfer/src/Helpers/Sources/AbstractSource.php#L46-L82","documentation":"Thrown as \\InvalidArgumentException with message 'wrong_columns_number' (AbstractImporter::ERROR_CODE_COLUMNS_NUMBER) while iterating an import source. AbstractSource::current() compares count(currentRowData) against totalColumns, the column count taken from the header row; a data row whose field count differs aborts the import. If the row also contains a stray single quote (foundWrongQuoteFlag), 'wrong_quotes' is thrown instead, so this error means the ragged row is NOT quote-related.","triggerScenarios":"Importing a CSV where a data row has more or fewer delimiters than the header (e.g. header with 5 columns, row with 6 because a value contains an unquoted comma); an Excel row with cells spilling past the header width; a trailing blank-but-delimited line like ',,,,' at end of file. Surfaces on the first current() call after next() reads the bad row.","commonSituations":"User-edited CSVs in Excel that re-save with different quoting; exports from other systems that pad or trim trailing columns; delimiter mismatch (file is semicolon-separated but ',' was passed, so fgetcsv splits into 1 column per row); hand-merged files with header rows repeated mid-file.","solutions":["Open the file at the row number reported by getCurrentRowNumber() and make its field count match the header (same number of delimiters, quote any value containing the delimiter).","Verify the delimiter passed to the CSV source matches the file's real separator (the constructor rejects mismatches, but a header-only match with ragged body rows still slips through fgetcsv).","Re-export from the source system with consistent quoting, or normalize the file with a pre-pass that pads/truncates rows to header width.","If your data legitimately contains quotes, fix those values first: rows with stray single quotes raise the separate wrong_quotes error and mask this one."],"exampleFix":"// before (row: \"SKU1,Red, Shirt, XL\" -> 4 fields vs 3-column header)\nSKU1,\"Red, Shirt\",XL\n// after: value containing the delimiter is quoted, field count matches header\nSKU1,\"Red, Shirt\",XL","handlingStrategy":"validation","validationCode":"// Pre-validate the CSV before handing it to the importer source\n$path = Storage::disk('private')->path($filePath);\n$handle = fopen($path, 'r');\n$header = fgetcsv($handle, 0, $delimiter, escape: '\\\\');\n$width = count($header);\n$badRows = [];\n$line = 1;\nwhile (($row = fgetcsv($handle, 0, $delimiter, escape: '\\\\')) !== false) {\n    $line++;\n    if (count($row) !== $width) {\n        $badRows[] = $line;\n    }\n}\nfclose($handle);\nif ($badRows !== []) {\n    throw new \\RuntimeException('Rows with wrong column count: '.implode(', ', $badRows));\n}","typeGuard":null,"tryCatchPattern":"try { foreach ($source as $row) { /* ... */ } } catch (\\InvalidArgumentException $e) { if ($e->getMessage() === AbstractImporter::ERROR_CODE_COLUMNS_NUMBER) { $rowNum = $source->getCurrentRowNumber(); // report row number + skip/abort } else { throw $e; } }","preventionTips":["Always quote CSV values that contain the delimiter when generating exports.","Reject or auto-fix ragged rows in a pre-pass instead of letting the iterator throw mid-import.","Pin the delimiter to what the header actually uses; a mismatch makes every row fail the column count check.","Surface getCurrentRowNumber() in import error reports so users can jump to the offending line."],"tags":["csv","data-import","validation","bagisto","php"],"backgroundTag":"csv-column-count-mismatch","analyzedSha":"c27a402253ed2bcee0f3eb16319fa7fc5eec5ffd","analyzedAt":"2026-08-21T04:19:34.141Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}