Hey everyone,
I recently ran into a couple of breaking changes when trying to convert a Lead, resulting in a 500 Internal Server Error. After digging into the backend logs and core files, I found two separate issues in ConvertService.php related to PHP 8 strictness and a recent architectural change regarding how created entities are returned.
I wanted to share the exact errors and the temporary patch I used to get it working in my Docker stack until an official fix is pushed.
1. The Breaking Changes & Errors
Issue 1: PHP 8 Strict Typing with count() When the conversion service processes array-type fields (like attachments or relational links) that happen to be empty (null), PHP 8 throws a fatal TypeError because it no longer allows counting a null value. Error output:
Plaintext
[2026-07-06 22:53:23] ERROR: Slim Application Error Type: TypeError Code: 0 Message: count(): Argument #1 ($value) must be of type Countable|array, null given File: /var/www/html/application/Espo/Modules/Crm/Tools/Lead/ConvertService.php Line: 203 Trace: #0 /var/www/html/application/Espo/Modules/Crm/Tools/Lead/ConvertService.php(203): count(NULL)
Issue 2: The CreateResult Wrapper Once the array counting was bypassed, the conversion failed again during the actual entity creation. In newer versions, passing CreateParams into $service->create() returns a CreateResult wrapper object rather than the raw entity itself. The script then attempts to call ->getAccount() on this wrapper, which crashes the process. Error output:
Plaintext
[2026-07-07 05:51:51] ERROR: Slim Application Error Type: Error Code: 0 Message: Call to undefined method Espo\Core\Record\CreateResult::getAccount() File: /var/www/html/application/Espo/Modules/Crm/Tools/Lead/ConvertService.php Line: 335
2. The Step-by-Step Fix
To resolve this, you need to edit /var/www/html/application/Espo/Modules/Crm/Tools/Lead/ConvertService.php.
Fixing the Array Counts: Find the count() checks for attachments and attributes (around lines 191 and 210). Add the null coalescing operator ?? [] so it safely counts an empty array instead of crashing on null.
Fixing the Entity Creation: Find the three instances where the Account, Contact, and Opportunity are created (around lines 274, 310, and 349). Append ->getEntity() to the end of each call so it successfully extracts the actual record from the wrapper.
3. Making the Fix Persistent in Docker Compose
If you are running EspoCRM in a Docker container, any rebuilt container will overwrite these core file edits. To make the patch survive container rebuilds until an official update is available, copy the patched ConvertService.php to your host machine and bind-mount it directly in your docker-compose.yml.
Add this directly to your EspoCRM service under the volumes section (adjusting the host path to match your specific environment):
YAML
volumes:
# Your existing volumes...
- /path/to/your/host/ConvertService.php:/var/www/html/application/Espo/Modules/Crm/Tools/Lead/ConvertService.php
Once added, redeploy your stack and clear the EspoCRM cache. Lead conversions will process perfectly.
Hope this helps anyone else running into the same roadblock!
I recently ran into a couple of breaking changes when trying to convert a Lead, resulting in a 500 Internal Server Error. After digging into the backend logs and core files, I found two separate issues in ConvertService.php related to PHP 8 strictness and a recent architectural change regarding how created entities are returned.
I wanted to share the exact errors and the temporary patch I used to get it working in my Docker stack until an official fix is pushed.
1. The Breaking Changes & Errors
Issue 1: PHP 8 Strict Typing with count() When the conversion service processes array-type fields (like attachments or relational links) that happen to be empty (null), PHP 8 throws a fatal TypeError because it no longer allows counting a null value. Error output:
Plaintext
[2026-07-06 22:53:23] ERROR: Slim Application Error Type: TypeError Code: 0 Message: count(): Argument #1 ($value) must be of type Countable|array, null given File: /var/www/html/application/Espo/Modules/Crm/Tools/Lead/ConvertService.php Line: 203 Trace: #0 /var/www/html/application/Espo/Modules/Crm/Tools/Lead/ConvertService.php(203): count(NULL)
Issue 2: The CreateResult Wrapper Once the array counting was bypassed, the conversion failed again during the actual entity creation. In newer versions, passing CreateParams into $service->create() returns a CreateResult wrapper object rather than the raw entity itself. The script then attempts to call ->getAccount() on this wrapper, which crashes the process. Error output:
Plaintext
[2026-07-07 05:51:51] ERROR: Slim Application Error Type: Error Code: 0 Message: Call to undefined method Espo\Core\Record\CreateResult::getAccount() File: /var/www/html/application/Espo/Modules/Crm/Tools/Lead/ConvertService.php Line: 335
2. The Step-by-Step Fix
To resolve this, you need to edit /var/www/html/application/Espo/Modules/Crm/Tools/Lead/ConvertService.php.
Fixing the Array Counts: Find the count() checks for attachments and attributes (around lines 191 and 210). Add the null coalescing operator ?? [] so it safely counts an empty array instead of crashing on null.
- Change: if (count($attachmentList)) {
- To: if (count($attachmentList ?? [])) {
- Change: if (count($attributeList) !== count($leadAttributeList)) {
- To: if (count($attributeList ?? []) !== count($leadAttributeList ?? [])) {
Fixing the Entity Creation: Find the three instances where the Account, Contact, and Opportunity are created (around lines 274, 310, and 349). Append ->getEntity() to the end of each call so it successfully extracts the actual record from the wrapper.
- Change: $account = $service->create($values, CreateParams::create()->withSkipDuplicateCheck());
- To: $account = $service->create($values, CreateParams::create()->withSkipDuplicateCheck())->getEntity(); (Make sure to repeat this exact change for both $contact and $opportunity as well).
3. Making the Fix Persistent in Docker Compose
If you are running EspoCRM in a Docker container, any rebuilt container will overwrite these core file edits. To make the patch survive container rebuilds until an official update is available, copy the patched ConvertService.php to your host machine and bind-mount it directly in your docker-compose.yml.
Add this directly to your EspoCRM service under the volumes section (adjusting the host path to match your specific environment):
YAML
volumes:
# Your existing volumes...
- /path/to/your/host/ConvertService.php:/var/www/html/application/Espo/Modules/Crm/Tools/Lead/ConvertService.php
Once added, redeploy your stack and clear the EspoCRM cache. Lead conversions will process perfectly.
Hope this helps anyone else running into the same roadblock!

Comment