Undefined array key "type" in Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::castValue()

Created on 11 March 2025, 7 months ago

Problem/Motivation

We have an issue when we want to change user's roles. The modifications are well applied in Drupal BO and in the DB but we have this warning. This is since a Drupal upgrade from 10.3.11 to 10.4.3.
We have role_delegation module installed.
We have this warning :

Warning : Undefined array key "type" dans Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::castValue() (/var/www/html/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php ligne 2570)
#0 /var/www/html/web/core/includes/bootstrap.inc(166): _drupal_error_handler_real()
#1 /var/www/html/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php(2570): _drupal_error_handler()
#2 /var/www/html/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php(1070): Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::castValue()
#3 /var/www/html/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php(1129): Drupal\Core\Entity\Sql\SqlContentEntityStorage->mapToStorageRecord()
#4 /var/www/html/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php(1015): Drupal\Core\Entity\Sql\SqlContentEntityStorage->mapToDataStorageRecord()
#5 /var/www/html/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php(935): Drupal\Core\Entity\Sql\SqlContentEntityStorage->saveToSharedTables()
#6 /var/www/html/web/core/modules/user/src/UserStorage.php(33): Drupal\Core\Entity\Sql\SqlContentEntityStorage->doSaveFieldItems()
#7 /var/www/html/web/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php(718): Drupal\user\UserStorage->doSaveFieldItems()
#8 /var/www/html/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php(486): Drupal\Core\Entity\ContentEntityStorageBase->doSave()
#9 /var/www/html/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php(806): Drupal\Core\Entity\EntityStorageBase->save()
#10 /var/www/html/web/core/lib/Drupal/Core/Entity/EntityBase.php(354): Drupal\Core\Entity\Sql\SqlContentEntityStorage->save()
#11 /var/www/html/web/core/modules/user/src/ProfileForm.php(46): Drupal\Core\Entity\EntityBase->save()
#12 [internal function]: Drupal\user\ProfileForm->save()
#13 /var/www/html/web/core/lib/Drupal/Core/Form/FormSubmitter.php(129): call_user_func_array()
#14 /var/www/html/web/core/lib/Drupal/Core/Form/FormSubmitter.php(67): Drupal\Core\Form\FormSubmitter->executeSubmitHandlers()
#15 /var/www/html/web/core/lib/Drupal/Core/Form/FormBuilder.php(597): Drupal\Core\Form\FormSubmitter->doSubmitForm()
#16 /var/www/html/web/core/lib/Drupal/Core/Form/FormBuilder.php(326): Drupal\Core\Form\FormBuilder->processForm()
#17 /var/www/html/web/core/lib/Drupal/Core/Controller/FormController.php(73): Drupal\Core\Form\FormBuilder->buildForm()
#18 /var/www/html/web/core/modules/layout_builder/src/Controller/LayoutBuilderHtmlEntityFormController.php(39): Drupal\Core\Controller\FormController->getContentResult()
#19 [internal function]: Drupal\layout_builder\Controller\LayoutBuilderHtmlEntityFormController->getContentResult()
#20 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array()
#21 /var/www/html/web/core/lib/Drupal/Core/Render/Renderer.php(638): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#22 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext()
#23 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext()
#24 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(181): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#25 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(76): Symfony\Component\HttpKernel\HttpKernel->handleRaw()
#26 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/Session.php(53): Symfony\Component\HttpKernel\HttpKernel->handle()
#27 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle()
#28 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/ContentLength.php(28): Drupal\Core\StackMiddleware\KernelPreHandle->handle()
#29 /var/www/html/web/core/modules/big_pipe/src/StackMiddleware/ContentLength.php(32): Drupal\Core\StackMiddleware\ContentLength->handle()
#30 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(116): Drupal\big_pipe\StackMiddleware\ContentLength->handle()
#31 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(90): Drupal\page_cache\StackMiddleware\PageCache->pass()
#32 /var/www/html/vendor/asm89/stack-cors/src/Cors.php(53): Drupal\page_cache\StackMiddleware\PageCache->handle()
#33 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Asm89\Stack\Cors->handle()
#34 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle()
#35 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php(36): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle()
#36 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php(51): Drupal\Core\StackMiddleware\AjaxPageState->handle()
#37 /var/www/html/web/core/lib/Drupal/Core/DrupalKernel.php(741): Drupal\Core\StackMiddleware\StackedHttpKernel->handle()
#38 /var/www/html/web/index.php(19): Drupal\Core\DrupalKernel->handle()
#39 {main}

Steps to reproduce

Go to BO and select a user then change his assigned roles and save.

Proposed resolution

Tried applying this patch as I saw that another patch was done for "Undefined array key "id"" in role_delegation module :

diff --git a/role_delegation.module b/role_delegation.module
index 0af744a..750b2e4 100644
--- a/role_delegation.module
+++ b/role_delegation.module
@@ -264,6 +264,11 @@
   // work without the 'administer users' permission. If another module has
   // already swapped out those classes, though, we'll be polite and do nothing.
   foreach ($definitions as &$definition) {
+    if (!isset($definition['type'])) {
+      \Drupal::logger('role_delegation')->warning("add missing field 'type' in a role change operation");
+      $definition['type'] = 'user'; // Valeur par dรฉfaut.
+    }
     if ($definition['id'] === 'user_add_role_action' && $definition['class'] === AddRoleUser::class) {
       $definition['class'] = RoleDelegationAddRoleUser::class;
     }
๐Ÿ› Bug report
Status

Active

Version

10.4 โœจ

Component

user system

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • ๐Ÿ‡ณ๐Ÿ‡ฟNew Zealand quietone

    Changes are made on on 11.x (our main development branch) first, and are then back ported as needed according to the Core change policies โ†’ .

    What is "Drupal BO"?

  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands ekes

    I've just triggered this warning as well:

    1) /var/www/html/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php:2567
    Undefined array key "type"                                                                                                                                              
    
    2) /var/www/html/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php:2570        
    Undefined array key "type" 
    

    but am confused by the OP.
    @lendod Did the patch on the Role Delegation module make any difference to your error?

    The code that is triggering this error is:

      public static function castValue(array $info, $value) {
        // Preserve legal NULL values.
        if (isset($value) || !empty($info['not null'])) {
          if ($info['type'] === 'int' || $info['type'] === 'serial') {
            return (int) $value;
          }
          elseif ($info['type'] === 'float') {
            return (float) $value;
          }
          return (string) $value;
        }
    
        return $value;
      }
    

    The $info['type'] in question here is the schema definition of the field as described in the Schema API documentation. Specifically:

    'type': The generic datatype: 'char', 'varchar', 'text', 'blob', 'int', 'float', 'numeric', or 'serial'. Most types just map to the according database engine specific data types. Use 'serial' for auto incrementing fields. This will expand to 'INT auto_increment' on MySQL. A special 'varchar_ascii' type is also available for limiting machine name field to US ASCII characters.

    Now according to the same documentation you can leave this unset. Which is what was happening in my case (the column has a database type check for 'mysql', so will only install on a MySQL DB, and includes a mysql_type key on the column field definition).

    'mysql_type', 'pgsql_type', 'sqlite_type', etc.: If you need to use a record type not included in the officially supported list of types above, you can specify a type for each database backend. In this case, you can leave out the type parameter, but be advised that your schema will fail to load on backends that do not have a type specified. A possible solution can be to use the "text" type as a fallback.

    So in the OP I wonder if it wasn't some other field that was causing the issue. I don't see anything obvious in Role Delegation that is adding more than a computed field.

    From the above I'd propose to make the MySQL backend fit present behavior (but without a warning) and also fit the documentation a isset should be added to the above code, making it.

      public static function castValue(array $info, $value) {
        // Preserve legal NULL values.
        if (isset($value) || !empty($info['not null'])) {
          if (isset($info['type'])) {
            if ($info['type'] === 'int' || $info['type'] === 'serial') {
              return (int) $value;
            }
            elseif ($info['type'] === 'float') {
              return (float) $value;
            }
          }
          return (string) $value;
        }
    
        return $value;
      }
    
  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands ekes
  • Pipeline finished with Failed
    3 months ago
    Total: 568s
    #552273
  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands ekes
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States smustgrave

    Change like this usually means an isset() is masking a larger issue shouldn't we address that so it's always set. May require test coverage.

  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands ekes

    Change like this usually means an isset() is masking a larger issue shouldn't we address that so it's always set.

    It's not going to be core code that is calling it with the key not set, because the reason for it not to be set is if you have a column that is only for a specific database backend, and has no fallback. The documented configuration for columns with no fallback is not to set one. So I'm not quite sure how you can make it always set? Changing the documentation (which I guess is an API??) to require a NULL when there isn't one at a guess?

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States smustgrave

    So if core isnโ€™t causing this wouldnโ€™t it be a bug in the contrib or custom module that is causing it?

  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands ekes

    So if core isnโ€™t causing this wouldnโ€™t it be a bug in the contrib or custom module that is causing it?

    As they are following the Schema API documentation. I don't think so. It would require a change to the requirements as documented for API (as quoted above) where it states that you can configure it with no fallback key set.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States smustgrave

    Can we clean up the summary some and then put back into review for additional eyes. Not sure the way forward for this one.

  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands ekes
  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands ekes
  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands ekes
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States smustgrave

    Since there's been no additional follow up maybe next step would be to add a test case that demonstrates the issue.

  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands ekes

    While there has not been any reply I've been trying out:

    > Check to see if requiring the type key with a NULL or (string) '' value works with the rest of the implementation and updating the API to make it required even when the type is database specific and there is no fallback,

    in my code

    ```
    $schema['columns']['start_utc'] = [
    'description' => 'Start DateTime.',
    'type' => NULL,
    'mysql_type' => 'datetime',
    ];
    ```

    and so far that's working.

    So the answer is maybe changing the API specification/documentation to reflect reality.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States smustgrave

    That I cannot answer unfortunately, sorry! But lets see if the sub-maintainer would know.

Production build 0.71.5 2024