Problem/Motivation
When navigating to /admin/structure/salesforce/mappings/manage/{mapping}, the following fatal error is thrown:
Error: Call to a member function render() on string in Drupal\salesforce_mapping_ui\Form\SalesforceMappingFormCrudBase->Drupal\salesforce_mapping_ui\Form\{closure}() (line 527 of modules/contrib/salesforce/modules/salesforce_mapping_ui/src/Form/SalesforceMappingFormCrudBase.php).
uasort(Array, Object) (Line: 526)
Drupal\salesforce_mapping_ui\Form\SalesforceMappingFormCrudBase->getEntityTypeOptions() (Line: 114)
Drupal\salesforce_mapping_ui\Form\SalesforceMappingFormCrudBase->buildForm(Array, Object)
call_user_func_array(Array, Array) (Line: 536)
Drupal\Core\Form\FormBuilder->retrieveForm('salesforce_mapping_edit_form', Object) (Line: 284)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 73)
Drupal\Core\Controller\FormController->getContentResult(Object, Object) (Line: 39)
Drupal\layout_builder\Controller\LayoutBuilderHtmlEntityFormController->getContentResult(Object, Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 638)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 121)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 181)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 76)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 53)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 28)
Drupal\Core\StackMiddleware\ContentLength->handle(Object, 1, 1) (Line: 263)
Drupal\shield\ShieldMiddleware->bypass(Object, 1, 1) (Line: 148)
Drupal\shield\ShieldMiddleware->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 36)
Drupal\Core\StackMiddleware\AjaxPageState->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object, 1, 1) (Line: 741)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)This has been observed in particular when using modules like ECK (Entity Construction Kit), which can cause entity labels to be stored simply as strings rather than TranslatableMarkup.
Steps to reproduce
1. Install and enable ECK contrib module.
2. Create a custom entity type using ECK (e.g., “My Custom Entity”).
3. Configure a Salesforce Mapping to map data to this ECK-based entity type.
4. Visit `/admin/structure/salesforce/mappings/manage/{mapping}`.
5. Receive fatal error: "Call to a member function render() on string".
Proposed resolution
Instead of calling $a->render() directly in `SalesforceMappingFormCrudBase::getEntityTypeOptions()`, cast both label objects to strings before comparing. This will handle both string and TranslatableMarkup:
// Old code:
return strcmp($a->render(), $b->render());
// New code:
return strcmp((string) $a, (string) $b);
This ensures the comparison works uniformly for both strings and TranslatableMarkup objects, preventing the fatal error.
Issue fork salesforce-3511455
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
dhruv.mittal commentedComment #4
dhruv.mittal commentedKindly review.
Comment #5
scott_euser commentedThis is exactly right. $option->label() there has return type of `string|\Drupal\Core\StringTranslation\TranslatableMarkup`, the latter has __toString() method, so `(string)` to each of these is right. Thanks!
Comment #9
aaronbaumancommitted, thanks