What is your set up?
Self Hosted Server
Version
3.7.3
Describe the issue
What is your set up?
Self-hosted, non-Docker (bare metal / VPS with PHP-FPM). Also reproduced by other users on Docker (see linked report).
Version: 3.7.3
PHP Version: 8.4 (also affects 8.1+ due to strict typed property enforcement introduced in PHP 8.0)
Describe the issue
Opening the plugin marketplace or attempting to install any plugin throws an HTTP 500. The root cause is that MarketplacePlugin.php declares several properties as non-nullable typed (public string $excerpt, public int $vendorId, etc.), but the Leantime marketplace API returns null for one or more of these fields at runtime. PHP 8.0+ strictly enforces typed property assignments and throws a TypeError on null assignment, regardless of whether a default value is set.
The raw assignment in Build.php:131 ($property->$key = $value) performs no null coercion before writing API data to the model, so any null field from the API hits the type constraint and crashes the request.
This renders the entire plugin system unusable.
(also creating a PR with the fix that worked for me; only tested on Debian 13 VPS host - after applying the patch, the plugins seem to be installing fine)
Reproduction steps
- Install Leantime 3.7.3 on PHP 8.x (Docker or bare metal)
- Navigate to the plugin marketplace
- Attempt to view or install any plugin
- HTTP 500 is returned immediately
- Optionally: attempt to install a licensed plugin, input a purchased license key, click Install — same result
Error Logs (LEANTIMEFOLDER/storage/logs)
Two distinct errors, both from the same root cause:
Cannot assign null to property
Leantime\Domain\Plugins\Models\MarketplacePlugin::$excerpt of type string
at /var/www/leantime/app/Core/Support/Build.php:131
TypeError (code: 0):
Cannot assign null to property
Leantime\Domain\Plugins\Models\MarketplacePlugin::$excerpt of type string
#0 /var/www/leantime/app/Core/Support/Build.php(29): Build->setValue()
#1 /var/www/leantime/app/Domain/Plugins/Hxcontrollers/Details.php(41): Build->set()
Also reported on Docker by another user with identical stacktrace:
json_decode(): Passing null to parameter #1 ($json) of type string
... /app/Domain/Plugins/Hxcontrollers/Details.php:35
Cannot assign null to property ... excerpt of type string
... /app/Core/Support/Build.php:131
Root cause
app/Domain/Plugins/Models/MarketplacePlugin.php declares these as non-nullable typed properties:
public string $identifier = '';
public string $name = '';
public string $excerpt = ''; // ← crashes here first
public string $description = '';
public string $imageUrl = '';
public string $vendorDisplayName = '';
public int $vendorId = 0; // ← also at risk
public string $vendorEmail = '';
public string $marketplaceUrl = '';
public string $type = 'marketplace';
public string $marketplaceId = '';
public string $version = '';
public string $icon = '';
Note: some fields ($startingPrice, $calculatedMonthlyPrice, $license, $rating) are already correctly declared as ?string = null, indicating this was partially addressed previously but not applied consistently.
The setter in app/Core/Support/Build.php:131 performs a raw assignment with no null guard:
$property->$key = $value; // no null coercion — crashes on typed non-nullable properties
Fix
Make all potentially-null API-sourced properties nullable. Minimal fix for MarketplacePlugin.php:
// Change all non-nullable string/int properties to nullable:
public ?string $identifier = '';
public ?string $name = '';
public ?string $excerpt = '';
public ?string $description = '';
public ?string $imageUrl = '';
public ?string $vendorDisplayName = '';
public ?int $vendorId = 0;
public ?string $vendorEmail = '';
public ?string $marketplaceUrl = '';
public ?string $type = 'marketplace';
public ?string $marketplaceId = '';
public ?string $version = '';
public ?string $icon = '';
A more durable systemic fix would also add null coercion in Build.php::setValue() so that all models built from external API data are protected, e.g.:
// Before raw assignment, coerce null based on declared type
$property->$key = $value ?? match($declaredType) {
'string' => '',
'int' => 0,
'array' => [],
default => null,
};
Additional context
This is deployment-agnostic — confirmed on both Docker Compose and bare-metal PHP-FPM installs. Any PHP 8.0+ deployment will hit this. PHP 7.x would have silently accepted the null assignment, which is why this may not have been caught before PHP 8.x became standard.
What is your set up?
Self Hosted Server
Version
3.7.3
Describe the issue
What is your set up?
Self-hosted, non-Docker (bare metal / VPS with PHP-FPM). Also reproduced by other users on Docker (see linked report).
Version: 3.7.3
PHP Version: 8.4 (also affects 8.1+ due to strict typed property enforcement introduced in PHP 8.0)
Describe the issue
Opening the plugin marketplace or attempting to install any plugin throws an HTTP 500. The root cause is that
MarketplacePlugin.phpdeclares several properties as non-nullable typed (public string $excerpt,public int $vendorId, etc.), but the Leantime marketplace API returnsnullfor one or more of these fields at runtime. PHP 8.0+ strictly enforces typed property assignments and throws aTypeErroron null assignment, regardless of whether a default value is set.The raw assignment in
Build.php:131($property->$key = $value) performs no null coercion before writing API data to the model, so any null field from the API hits the type constraint and crashes the request.This renders the entire plugin system unusable.
(also creating a PR with the fix that worked for me; only tested on Debian 13 VPS host - after applying the patch, the plugins seem to be installing fine)
Reproduction steps
Error Logs (LEANTIMEFOLDER/storage/logs)
Two distinct errors, both from the same root cause:
Also reported on Docker by another user with identical stacktrace:
Root cause
app/Domain/Plugins/Models/MarketplacePlugin.phpdeclares these as non-nullable typed properties:Note: some fields (
$startingPrice,$calculatedMonthlyPrice,$license,$rating) are already correctly declared as?string = null, indicating this was partially addressed previously but not applied consistently.The setter in
app/Core/Support/Build.php:131performs a raw assignment with no null guard:Fix
Make all potentially-null API-sourced properties nullable. Minimal fix for
MarketplacePlugin.php:A more durable systemic fix would also add null coercion in
Build.php::setValue()so that all models built from external API data are protected, e.g.:Additional context
This is deployment-agnostic — confirmed on both Docker Compose and bare-metal PHP-FPM installs. Any PHP 8.0+ deployment will hit this. PHP 7.x would have silently accepted the null assignment, which is why this may not have been caught before PHP 8.x became standard.