{"record":{"id":"6cb4a178061e1f53","repo":"PHPOffice/PhpSpreadsheet","slug":"trend-number-of-elements-in-coordinate-arrays-d","errorCode":null,"errorMessage":"Trend(): Number of elements in coordinate arrays do not match.","messagePattern":"Trend\\(\\): Number of elements in coordinate arrays do not match\\.","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Shared/Trend/Trend.php","lineNumber":68,"sourceCode":"\n    /**\n     * @param mixed[] $yValues\n     * @param mixed[] $xValues\n     */\n    public static function calculate(string $trendType = self::TREND_BEST_FIT, array $yValues = [], array $xValues = [], bool $const = true): BestFit\n    {\n        //    Calculate number of points in each dataset\n        /** @var float[] $xValues */\n        $nY = count($yValues);\n        /** @var float[] $xValues */\n        $nX = count($xValues);\n\n        //    Define X Values if necessary\n        if ($nX === 0) {\n            $xValues = range(1, $nY);\n        } elseif ($nY !== $nX) {\n            //    Ensure both arrays of points are the same size\n            throw new SpreadsheetException('Trend(): Number of elements in coordinate arrays do not match.');\n        }\n\n        $key = md5($trendType . $const . serialize($yValues) . serialize($xValues));\n        //    Determine which Trend method has been requested\n        switch ($trendType) {\n            //    Instantiate and return the class for the requested Trend method\n            case self::TREND_LINEAR:\n            case self::TREND_LOGARITHMIC:\n            case self::TREND_EXPONENTIAL:\n            case self::TREND_POWER:\n                if (!isset(self::$trendCache[$key])) {\n                    /** @var float[] $yValues */\n                    $className = '\\PhpOffice\\PhpSpreadsheet\\Shared\\Trend\\\\' . $trendType . 'BestFit';\n                    /** @var float[] $xValues */\n                    self::$trendCache[$key] = new $className($yValues, $xValues, $const);\n                }\n\n                return self::$trendCache[$key];","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Shared/Trend/Trend.php#L50-L86","documentation":"Thrown by Trend::trend() when non-empty X and Y arrays have different element counts. The method happily invents X values (range(1, n)) only when X is omitted entirely ($nX === 0); otherwise equal size is mandatory and a mismatch is rejected up front, before any cache key or regression class is built.","triggerScenarios":"Trend::trend($trendType, $yValues, $xValues) with count($yValues) !== count($xValues), e.g. 12 monthly Y values against 11 X labels after an off-by-one slice, or X filtered while Y wasn't. Direct construction of BestFit subclasses (LinearBestFit etc.) performs the same check via parent::__construct($yValues, $xValues).","commonSituations":"Dataset assembled from separate queries/sources whose row counts drift; array_filter applied to one axis only; a trailing summary row appended to Y; nulls removed from one series but not the other.","solutions":["Align the series before calling: ensure count($xValues) === count($yValues) (e.g. array_slice to the shorter, or rebuild both from one list of [x, y] pairs).","Omit X entirely when it is just an index: Trend::trend($type, $yValues) generates 1..n automatically and cannot mismatch.","If pairs may be ragged, normalize first: filter both arrays with the same predicate so entries drop in lockstep.","Add a guard in your data-prep layer that throws a descriptive error naming both counts."],"exampleFix":"// before\n$fit = Trend::trend(Trend::TREND_LINEAR, $yValues, $xValues);\n// Trend(): Number of elements in coordinate arrays do not match. (12 vs 11)\n\n// after\nassert(count($yValues) === count($xValues));\n// rebuild both from shared pairs so they can't drift:\nforeach ($points as ['x' => $x[], 'y' => $y[]]) {}\n$fit = Trend::trend(Trend::TREND_LINEAR, $y, $x);","handlingStrategy":"validation","validationCode":"if (count($xValues) !== count($yValues)) {\n    $n = min(count($xValues), count($yValues));\n    $xValues = array_slice($xValues, 0, $n);\n    $yValues = array_slice($yValues, 0, $n); // or throw with both counts in the message\n}\n$fit = Trend::trend($type, $yValues, $xValues);","typeGuard":null,"tryCatchPattern":"try { $fit = Trend::trend($type, $yValues, $xValues); }\ncatch (\\PhpOffice\\PhpSpreadsheet\\Exception $e) {\n    if (str_contains($e->getMessage(), 'coordinate arrays do not match')) {\n        throw new InvalidArgumentException(sprintf(\n            'X/Y size mismatch (%d vs %d)', count($xValues), count($yValues)\n        ), 0, $e);\n    }\n    throw $e;\n}","preventionTips":["Build both series from one list of pairs so they cannot drift apart.","Omit $xValues when it is just an index — Trend generates 1..n and skips the check.","Apply the same filter predicate to both axes when dropping invalid points."],"tags":["trend-analysis","input-validation","arrays","phpspreadsheet"],"backgroundTag":"array-length-mismatch","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}