BookStackApp/BookStack · error · ThemeModuleException
Module in folder "{$folderName}" is missing a valid 'version
Error message
Module in folder "{$folderName}" is missing a valid 'version' property What it means
ThemeModuleException guard in ThemeModule::fromJson rejecting a bookstack-module.json manifest whose 'version' value is absent or not a string. Input at fault: the module's JSON manifest with an invalid version field.
Source
Thrown at app/Theming/ThemeModule.php:31
}
/**
* Create a ThemeModule instance from JSON data.
*
* @throws ThemeModuleException
*/
public static function fromJson(array $data, string $folderName): self
{
if (empty($data['name']) || !is_string($data['name'])) {
throw new ThemeModuleException("Module in folder \"{$folderName}\" is missing a valid 'name' property");
}
if (!isset($data['description']) || !is_string($data['description'])) {
throw new ThemeModuleException("Module in folder \"{$folderName}\" is missing a valid 'description' property");
}
if (!isset($data['version']) || !is_string($data['version'])) {
throw new ThemeModuleException("Module in folder \"{$folderName}\" is missing a valid 'version' property");
}
if (!preg_match('/^v?\d+\.\d+\.\d+(-.*)?$/', $data['version'])) {
throw new ThemeModuleException("Module in folder \"{$folderName}\" has an invalid 'version' format. Expected semantic version format like '1.0.0' or 'v1.0.0'");
}
return new self(
name: $data['name'],
description: $data['description'],
version: $data['version'],
folderName: $folderName,
);
}
/**
* Get a path for a file within this module.
*/
public function path($path = ''): stringView on GitHub (pinned to 18f8469a1c)
Solutions
- Add a 'version' key as a quoted string, e.g. "1.0.0"
- Quote numeric versions — unquoted JSON numbers fail the is_string check
- Follow semantic version format to also pass the next validation (see error 126)
- Bump the version string when republishing a fixed module
Example fix
// before
{ "version": 1.0 }
// after
{ "version": "1.0.0" } Defensive patterns
Strategy: validation
Validate before calling
function validateVersionPresent(array $data, string $folder): void {
if (!isset($data['version']) || !is_string($data['version'])) {
throw new InvalidArgumentException("Module in folder \"{$folder}\" needs a string 'version'");
}
} Type guard
function hasStringVersion(array $data): bool {
return isset($data['version']) && is_string($data['version']);
} Try / catch
try {
$module = ThemeModule::fromJson($data, $folderName);
} catch (ThemeModuleException $e) {
if (str_contains($e->getMessage(), "'version' property")) {
// instruct author to add a quoted semver string
}
} Prevention
- Always quote version values in JSON: "version": "1.0.0", never 1.0
- Use a JSON schema validator on module descriptors before packaging
- Keep versions as strings in any build tooling that generates descriptors
- Review descriptors after automated edits/generators
When it happens
Trigger: fromJson receives $data where 'name' and 'description' are valid but 'version' is absent, null, or a non-string value (e.g. a float like 1.0 written without quotes, which PHP decodes as a number).
Common situations: Authors writing "version": 1.0 (unquoted number) in JSON; descriptors copied from templates without a version; hand-edited files where the version line was deleted.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Module in folder "{$folderName}" has an invalid 'version' fo
- Module in folder "{$folderName}" is missing a valid 'name' p
- Module in folder "{$folderName}" is missing a valid 'descrip
- Failed to load module from zip file after extraction
- Book to move chapter into not found
AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02).
Data as JSON: /api/errors/314e93cd54dba74e.
Report an issue: GitHub.