getgrav/grav · critical · RuntimeException
Uploaded archive file is not a valid Grav update package
Error message
Uploaded archive file is not a valid Grav update package
What it means
DirectInstallCommand::upgradeGrav() validates that the extracted archive is a genuine Grav core update package: it must contain system/install.php which, when included, returns a callable that performs the install. If that file is absent or does not return a callable, the archive is rejected with this RuntimeException (whose message is then stored via Installer::setError).
Source
Thrown at system/src/Grav/Console/Gpm/DirectInstallCommand.php:315
/**
* @param string $zip
* @param string $folder
* @return void
*/
private function upgradeGrav(string $zip, string $folder): void
{
if (!is_dir($folder)) {
Installer::setError('Invalid source folder');
}
try {
$script = $folder . '/system/install.php';
/** Install $installer */
if ((file_exists($script) && $install = include $script) && is_callable($install)) {
$install($zip);
} else {
throw new RuntimeException('Uploaded archive file is not a valid Grav update package');
}
} catch (Exception $e) {
Installer::setError($e->getMessage());
}
}
}
View on GitHub (pinned to 6040efed04)
Solutions
- Use the official package: download from getgrav.org/download (e.g. grav-v1.7.x.zip) and run `bin/gpm direct-install grav-v1.7.x.zip`.
- Verify the archive layout before installing: `unzip -l package.zip | grep 'system/install.php'` — it must sit at the package root.
- Re-download the package if the zip is truncated (compare size/checksum) and retry.
- If you must install from source, replicate the packaging so system/install.php returning a closure is included at the root.
Example fix
# before $ unzip -l grav-source-tag.zip # no system/install.php -> error $ bin/gpm direct-install grav-source-tag.zip # after $ wget https://getgrav.org/download/core/grav/1.7.46 -O grav-upgrade.zip $ unzip -l grav-upgrade.zip # contains system/install.php $ bin/gpm direct-install grav-upgrade.zip
Defensive patterns
Strategy: validation
Validate before calling
// validate the archive before direct-install
$zip = new \ZipArchive();
if ($zip->open($path) !== true || $zip->locateName('system/install.php') === false) {
exit('Not a valid Grav update package (missing system/install.php); download from getgrav.org' . PHP_EOL);
}
$zip->close();
// proceed: passthru('php bin/gpm direct-install ' . escapeshellarg($path)); Prevention
- Only feed `bin/gpm direct-install` packages obtained from getgrav.org/download.
- Pre-check every archive with `unzip -l pkg.zip | grep system/install.php`.
- Pin and checksum downloads so truncated files are caught before they reach GPM.
When it happens
Trigger: Running `bin/gpm direct-install package.zip` with a GitHub 'Source code (zip)' auto-generated archive (no system/install.php), a plugin or theme zip instead of a core Grav package, a manually repacked/filtered zip that dropped system/install.php, or a truncated/corrupted download that extracted incompletely.
Common situations: Trying to update Grav from a GitHub release tag instead of the official getgrav.org package; feeding a locally built artifact into direct-install; downloading over a flaky connection so the zip is cut short; using direct-install on a zip that only contains the grav/ subfolder rather than the package root layout.
Related errors
- Uploaded archive file is not a valid Grav update package
- Following requirements have failed:
- 400
- Could not migrate the Twig-sandbox allowlists to the additiv
- No backups defined...
AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17).
Data as JSON: /api/errors/d59b0ceb640879ae.
Report an issue: GitHub.