getgrav/grav · error · RuntimeException
Bad Data
Error message
Bad Data
What it means
DataFile::load() reads raw bytes via parent::load() (file_get_contents) and requires a string; anything else throws 'Bad Data'. file_get_contents returns false exactly when the read failed — file missing, unreadable by the PHP user, or blocked by open_basedir — so despite the message the real cause is a failed read, not corrupt content. DataFile immediately re-wraps it as "Failed to load file '...': Bad Data" with this as the previous exception.
Source
Thrown at system/src/Grav/Framework/File/DataFile.php:49
*/
public function __construct($filepath, FileFormatterInterface $formatter)
{
parent::__construct($filepath);
$this->formatter = $formatter;
}
/**
* {@inheritdoc}
* @see FileInterface::load()
*/
public function load()
{
$raw = parent::load();
try {
if (!is_string($raw)) {
throw new RuntimeException('Bad Data');
}
return $this->formatter->decode($raw);
} catch (RuntimeException $e) {
throw new RuntimeException(sprintf("Failed to load file '%s': %s", $this->getFilePath(), $e->getMessage()), $e->getCode(), $e);
}
}
/**
* {@inheritdoc}
* @see FileInterface::save()
*/
public function save($data): void
{
if (is_string($data)) {
// Make sure that the string is valid data.
try {
$this->formatter->decode($data);View on GitHub (pinned to 6040efed04)
Solutions
- Check existence and readability before loading: is_file($path) && is_readable($path); treat 'missing' as empty state and initialize defaults instead of calling load().
- Fix ownership/mode of the file for the PHP user (chown/chmod).
- Confirm the path is absolute, correctly spelled, and within open_basedir.
- If the file was half-written by an earlier crash, restore from backup or delete it so defaults regenerate.
Example fix
// before $data = $dataFile->load(); // RuntimeException: Bad Data // after $path = $dataFile->getFilePath(); $data = (is_file($path) && is_readable($path)) ? $dataFile->load() : $defaults;
Defensive patterns
Strategy: validation
Validate before calling
$path = $dataFile->getFilePath();
if (!is_file($path) || !is_readable($path)) {
// load() would throw 'Bad Data'; treat as empty state and use defaults
return $defaults;
} Try / catch
try {
$data = $dataFile->load();
} catch (\RuntimeException $e) {
// message contains path + 'Bad Data': file missing/unreadable
$data = $defaults;
} Prevention
- Use a create-if-missing pattern: save defaults on first run so the file exists.
- Keep file ownership aligned with the PHP user across CLI/web usage.
- Check file presence after restores and migrations before enabling readers.
When it happens
Trigger: DataFile::load() on a file that does not exist yet (first run before save, deleted data), is not readable by the PHP user (wrong ownership/mode), or sits outside open_basedir.
Common situations: Plugins reading user/data files before ever creating them; files created by a root CLI run so the web user cannot read; migrations copying files without preserving modes; shared hosting with path restrictions.
Related errors
- Creating directory failed for {filepath}
- Opening file for writing failed on error {$message}
- Failed to save file {filepath}
- Failed to load file '%s': %s
- Failed to save file '%s': %s
AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17).
Data as JSON: /api/errors/d991eb4d14e8283a.
Report an issue: GitHub.