{"id":"343f1320333959a1","repo":"laravel/framework","slug":"dump-execution-exceeded-maximum-depth-of-30","errorCode":null,"errorMessage":"Dump execution exceeded maximum depth of 30.","messagePattern":"Dump execution exceeded maximum depth of 30\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Database/Schema/MySqlSchemaState.php","lineNumber":182,"sourceCode":"            'LARAVEL_LOAD_SSL_KEY' => $config['options'][Mysql::ATTR_SSL_KEY] ?? '',\n        ];\n    }\n\n    /**\n     * Execute the given dump process.\n     *\n     * @param  \\Symfony\\Component\\Process\\Process  $process\n     * @param  callable  $output\n     * @param  array  $variables\n     * @param  int  $depth\n     * @return \\Symfony\\Component\\Process\\Process\n     *\n     * @throws \\Throwable\n     */\n    protected function executeDumpProcess(Process $process, $output, array $variables, int $depth = 0)\n    {\n        if ($depth > 30) {\n            throw new Exception('Dump execution exceeded maximum depth of 30.');\n        }\n\n        try {\n            $process->setTimeout(null)->mustRun($output, $variables);\n        } catch (Exception $e) {\n            if (Str::contains($e->getMessage(), ['column-statistics', 'column_statistics'])) {\n                return $this->executeDumpProcess(Process::fromShellCommandLine(\n                    str_replace(' --column-statistics=0', '', $process->getCommandLine())\n                ), $output, $variables, $depth + 1);\n            }\n\n            if (str_contains($e->getMessage(), 'set-gtid-purged')) {\n                return $this->executeDumpProcess(Process::fromShellCommandLine(\n                    str_replace(' --set-gtid-purged=OFF', '', $process->getCommandLine())\n                ), $output, $variables, $depth + 1);\n            }\n\n            throw $e;","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/laravel/framework/blob/bd6b5437e6ad87bb49f9b426724f07a9f64e9683/src/Illuminate/Database/Schema/MySqlSchemaState.php#L164-L200","documentation":"MySqlSchemaState.executeDumpProcess() recurses to retry mysqldump after stripping incompatible flags (--column-statistics, --set-gtid-purged). A hard depth cap of 30 prevents infinite recursion if each retry keeps failing in a way that matches the retry patterns. Hitting it means the dump repeatedly failed-and-retried 30 times.","triggerScenarios":"Running schema:dump (or the test harness that calls it) where mysqldump keeps failing on --column-statistics or --set-gtid-purged and the error message still contains those substrings after the flag is stripped — e.g. a mysqldump version mismatch where the error text mentions the flag but stripping it does not resolve the underlying failure. Each recursive call increments depth until 30 is exceeded.","commonSituations":"mysqldump client/server version skew (8.0 client vs older server); MariaDB vs MySQL flag differences; corrupted installation where the flag-stripping heuristic loops; CI images with mismatched mysql-client versions.","solutions":["Inspect the actual mysqldump error by running the dump command manually — the depth cap masks the root cause.","Align the mysql-client version with the server version (e.g. pin mysql-client in your Docker/CI image).","If using MariaDB, ensure the schema state class is the MariaDbSchemaState (use a MariaDB driver), not MySQL's.","Upgrade or downgrade mysqldump until --column-statistics / --set-gtid-purged are natively handled."],"exampleFix":"// before — schema:dump loops on version-skewed mysqldump\nArtisan::call('schema:dump');\n\n// after — run the failing dump by hand to read the real error\n// $ mysqldump -u root -p db --column-statistics=0 > out.sql\n// then pin the matching client in CI, e.g. compose.yml:\n// services:\n//   mysql:\n//     image: mysql:8.0\n//   artisan:\n//     image: yourapp:php\n//     depends_on: [mysql]\n//     # install mysql-client 8.0 to match the server","handlingStrategy":"try-catch","validationCode":"// No programmatic pre-check; surface real mysqldump error instead.\n// Run the dump command manually first:\n// $ mysqldump -u $DB_USER -p$DB_PASS $DB_DB --column-statistics=0 > /tmp/probe.sql","typeGuard":null,"tryCatchPattern":"try {\n    Artisan::call('schema:dump');\n} catch (\\Exception $e) {\n    if (str_contains($e->getMessage(), 'maximum depth of 30')) {\n        // run mysqldump manually to read the real error; align client/server versions\n        throw new \\RuntimeException('schema:dump looped; run mysqldump manually to diagnose', 0, $e);\n    }\n    throw $e;\n}","preventionTips":["Pin the mysql-client version to match the server in CI and Docker images.","Use MariaDbSchemaState for MariaDB, not the MySQL one.","Run mysqldump manually whenever schema:dump behaves oddly to read the underlying error."],"tags":["database","mysql","schema-dump","tooling","version-mismatch"],"analyzedSha":"bd6b5437e6ad87bb49f9b426724f07a9f64e9683","analyzedAt":"2026-08-06T00:28:32.783Z","schemaVersion":2}