Problem/Motivation

When I visit node add I recibe a "Call to a member function getAccountName() on null " error.
Here is the full message.

Error: Call to a member function getAccountName() on null en Drupal\node\NodeForm->form() (línea 155 de /var/www/html/web/core/modules/node/src/NodeForm.php)
#0 /var/www/html/web/core/lib/Drupal/Core/Entity/EntityForm.php(106): Drupal\node\NodeForm->form(Array, Object(Drupal\Core\Form\FormState))

Steps to reproduce

Visit node/add/[Bundle] where uid's default value is somehow NULL
Visit node/edit/nid when the user for the node has been deleted and the content still exists.

Proposed resolution

Add defence to NodeForm to protect from a NULL return from $node->getOwner()
Don't show anything in the Node meta information when author is NULL
Example when author is NULL

Issue fork drupal-3161212

Command icon 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

eduardo morales alberti’s picture

Added patch to retrieve the author from current user if node is new.

nitesh pawar’s picture

Hi Eduardo Morales Alberti,

The issue is not replicated to me. I have tried to create content with the admin user and it created the node without any errors and error logs.
Can you provide the steps to replicate it?

shailja179’s picture

Hi Eduardo Morales Alberti,

Are you doing any custom stuff on node add? Because on fresh Drupal 9.1, issue could not be replicated.
Please add steps to reproduce the issue.

berdir’s picture

Status: Active » Closed (duplicate)
droodpal’s picture

Eduardo Morales Alberti, after your patch it is possible to create an Article, however in the Error Log there are other calls that trigger the node callback. Doesn't solve the other references.
Similar issue here

mihailnovak’s picture

I have the same problem.
After upgrading from Drupal 8.9.11 to Drupal 9.1
When I try to add new content
# 2 Works for me

Drupal 9.1
PHP 7.4.11
10.3.27-MariaDB

The patch works for me, but again a warning

Location https://migrantlife.bg/node/add/article
Referrer https://migrantlife.bg/node/add

Warning: call_user_func() expects parameter 1 to be a valid callback, class 'Drupal\node\Entity\Node' does not have a method 'getCurrentUserId' in Drupal\Core\Field\FieldConfigBase->getDefaultValue() (line 398 of /home/refugeel/public_html/core/lib/Drupal/Core/Field/FieldConfigBase.php)
#0 /home/refugeel/public_html/core/includes/bootstrap.inc(305): _drupal_error_handler_real(2, 'call_user_func(...', '/home/refugeel/...', 398)
#1 [internal function]: _drupal_error_handler(2, 'call_user_func(...', '/home/refugeel/...', 398, Array)
#2 /home/refugeel/public_html/core/lib/Drupal/Core/Field/FieldConfigBase.php(398): call_user_func('Drupal\\node\\Ent...', Object(Drupal\node\Entity\Node), Object(Drupal\Core\Field\Entity\BaseFieldOverride))
#3 /home/refugeel/public_html/core/lib/Drupal/Core/Field/FieldItemList.php(169): Drupal\Core\Field\FieldConfigBase->getDefaultValue(Object(Drupal\node\Entity\Node))
#4 /home/refugeel/public_html/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php(177): Drupal\Core\Field\FieldItemList->applyDefaultValue()
#5 /home/refugeel/public_html/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php(119): Drupal\Core\Entity\ContentEntityStorageBase->initFieldValues(Object(Drupal\node\Entity\Node), Array)
#6 /home/refugeel/public_html/core/lib/Drupal/Core/Entity/EntityStorageBase.php(216): Drupal\Core\Entity\ContentEntityStorageBase->doCreate(Array)
#7 /home/refugeel/public_html/core/lib/Drupal/Core/Entity/EntityForm.php(370): Drupal\Core\Entity\EntityStorageBase->create(Array)
#8 /home/refugeel/public_html/core/lib/Drupal/Core/Entity/HtmlEntityFormController.php(73): Drupal\Core\Entity\EntityForm->getEntityFromRouteMatch(Object(Drupal\Core\Routing\RouteMatch), 'node')
#9 /home/refugeel/public_html/core/lib/Drupal/Core/Controller/FormController.php(58): Drupal\Core\Entity\HtmlEntityFormController->getFormObject(Object(Drupal\Core\Routing\RouteMatch), 'node.default.de...')
#10 [internal function]: Drupal\Core\Controller\FormController->getContentResult(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\RouteMatch))
#11 /home/refugeel/public_html/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#12 /home/refugeel/public_html/core/lib/Drupal/Core/Render/Renderer.php(573): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#13 /home/refugeel/public_html/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#14 /home/refugeel/public_html/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#15 /home/refugeel/public_html/vendor/symfony/http-kernel/HttpKernel.php(158): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#16 /home/refugeel/public_html/vendor/symfony/http-kernel/HttpKernel.php(80): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#17 /home/refugeel/public_html/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#18 /home/refugeel/public_html/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#19 /home/refugeel/public_html/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#20 /home/refugeel/public_html/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#21 /home/refugeel/public_html/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#22 /home/refugeel/public_html/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#23 /home/refugeel/public_html/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#24 /home/refugeel/public_html/core/lib/Drupal/Core/DrupalKernel.php(706): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#25 /home/refugeel/public_html/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#26 {main}

Steven McCoy’s picture

In my case, I was able to resolve this by editing my config override files, and then re-importing them. I guess the method name changed somewhere along the way, but not in a way that updated my site's config. Updating those config overrides was a much simpler and more elegant solution than patching Drupal's codebase to accommodate this disconnect.

Example 1:
'Drupal\node\Entity\Node::getCurrentUserId' needed to become 'Drupal\node\Entity\Node::getDefaultEntityOwner'

Example 2:
'Drupal\media\Entity\Media::getCurrentUserId' needed to become 'Drupal\media\Entity\Media::getDefaultEntityOwner'

rossidrup’s picture

can you please give me more info?
I get this error

e website encountered an unexpected error. Please try again later.
Error: Call to a member function getAccountName() on null in Drupal\node\NodeForm->form() (line 155 of core/modules/node/src/NodeForm.php).
Drupal\node\NodeForm->form(Array, Object) (Line: 106)
Drupal\Core\Entity\EntityForm->buildForm(Array, Object)
call_user_func_array(Array, Array) (Line: 532)
Drupal\Core\Form\FormBuilder->retrieveForm('node_page_form', Object) (Line: 278)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 73)
Drupal\Core\Controller\FormController->getContentResult(Object, Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 578)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 158)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 80)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 716)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

kedramon’s picture

Answer from #8 is the best, no need for the patch, I got this after core update from 8 to 9.
Just search inside your config directory for ::getCurrentUserId and replace it with ::getDefaultEntityOwner
and then import the config, and that's all. Good luck!

bakulahluwalia’s picture

@kedramon the suggested solution at #10 didn't work for me.
Patch #2 worked but there is still a warning message coming in the logs.

rp7’s picture

Answer in #8 did the trick for me. Thank you!

attraktive’s picture

#8 and #10 perfect ;)
thanks !

nicxvan’s picture

Number 8 worked for me too.

isaacrc’s picture

#8 Worked for me. Thanks!

bajah1701’s picture

Anyone looking for a more explicit solution to this problem visit https://www.drupal.org/project/drupal/issues/3153455

srihari manepally’s picture

#8 worked for me. Thanks.

joakland’s picture

#8 worked for me as well, though I needed to make the change in the config table in the database, not in an imported config file. And the call to ::getCurrentUserId was in a serialized array. More database surgery than I usually care to do. But at least it's all working now.

tsotoodeh’s picture

thomaswalther’s picture

Patch #2 worked for me after updating Drupal 8.9.20 to 9.3.3. Thanks!

devil2005’s picture

Not for me, another warning appears... drupal 9.3.3 :(

tsotoodeh’s picture

@devil2005
try the following query on the database. After the D8 to D9 migration this should be done.

UPDATE config
  SET data = REPLACE(data, 's:41:"Drupal\\node\\Entity\\Node::getCurrentUserId"', 's:46:"Drupal\\node\\Entity\\Node::getDefaultEntityOwner"')
  WHERE data LIKE '%getCurrentUserId%';

good luck

mazze’s picture

Thank you @tsotoodeh, you made my day... I had to run update.php, and it's working now:-)

alexpertsi’s picture

Thank you #22 @tsotoodeh!!!! Also worked for my drupal 8.9.16 to 9.3.3!

asubit’s picture

asubit’s picture

I propose a new version of the patch that uses the dependency injection already present to recover the current user.

organicwire’s picture

#22 fixes the problem for me. Instead of using SQL, you can use config management to do the fix. I'm on Drupal 9.3.3.

Use drush to edit the node type's config and replace getCurrentUserId with getDefaultEntityOwner.

$ drush config:edit core.base_field_override.node.YOUR_CONTENT_TYPE.uid

# Old line:
default_value_callback: 'Drupal\node\Entity\Node::getCurrentUserId'
# Replaced line:
default_value_callback: 'Drupal\node\Entity\Node::getDefaultEntityOwner'
solimanharkas’s picture

#8 Worked for me. Thank you!

pawel_r’s picture

#8 and #10 helped in my case, thanks!

rollinstudios’s picture

#8 and #10 worked for me on Drupal 9.4.8

david radcliffe’s picture

Patch #2 solved my problem, but I would like to understand it better. Does this patch fix an error in NodeForm.php, or is it a workaround for an error that may lie elsewhere? Should we expect that $node->getOwner() is not null when we retrieve the author? I am using Drupal 9.5.2 and PHP 8.1.14 with the Group module and a lot of custom code.

sandeepsingh199’s picture

StatusFileSize
new1015 bytes

Hi, I added some more checks

+    // Set default author.
+    $meta_author = \Drupal::currentUser()->getAccountName();
+    if (!$node->isNew() && $node->getOwner() != null) {
+      $meta_author = $node->getOwner()->getAccountName();
+    }
joseph.olstad’s picture

Version: 9.1.x-dev » 11.1.x-dev

Hitting this with D11 , client deleted a user

joseph.olstad’s picture

Title: Node add gives a Call to a member function getAccountName() on null Drupal 9 » Node add/edit gives a Call to a member function getAccountName() on null Drupal 11
Assigned: Unassigned » joseph.olstad
Status: Closed (duplicate) » Active

joseph.olstad’s picture

Suggested workarounds from comment #8 and related suggestions did not yield any clues. Patch 32 works for us. Our client deleted some users in prod that were involved in site building and some specific use cases involving content. Result is a WSOD for related environments when doing a node edit. The page in question has nothing special, just a node form with some normal fields. The reference to the user that is null is somewhere in a revision or as author/owner. This is about all the meta I can provide at this time.

sivaji_ganesh_jojodae’s picture

Status: Active » Needs work

> changed target branch from 11.x to 11.1.x

Should be 11.x

nicxvan’s picture

Version: 11.1.x-dev » 11.x-dev
catch’s picture

Component: forms system » node system
Issue tags: +Needs tests
catch’s picture

The issue title says node/add but that looks like a very old config export that was fixed in a different issue.

berdir’s picture

It doesn't make sense to fall back to the current user. If there is no current owner, it shouldn't display anything. it will afaik set the current user then as owner on save, but it's not yet true. So it should just not display anything then.

This _should_ not happen, deleting users should either delete the content or reassign it, this is just about dealing with invalid data.

And yes, originally the issue was about problems with the default value config that wasn't updated, I think a new issue would have made more sense, but it's technically speaking that error.

catch’s picture

It doesn't make sense to fall back to the current user. If there is no current owner, it shouldn't display anything. it will afaik set the current user then as owner on save, but it's not yet true. So it should just not display anything then.

Yes agreed with this, and should possibly trigger_error() an E_USER_WARNING since it could be the result of a botched database update or attempt to prune user accounts and similar.

joseph.olstad’s picture

Assigned: joseph.olstad » Unassigned

While it shouldn't happen, it did for us and it is content or revision related however it's possible that contrib or custom code is involved. We have about 6 environments of the same build. My copy is a production dump from before the client deleted users. In my copy, I do not see the exception however in the more recent production copy where the users were deleted there is an exception that occurs when trying to edit the node associated to a deleted user and the patch is needed in this case. I'm guessing that the delete option that was chosen by the client resulted in an orphaned uid in a revision or field or a related contrib row value where uid [0-9][0-9] did not get assigned to uid 0.

It could possibly be related to a content_lock being held by a deleted user. Therefore this would be a contrib related issue.

So 100% the configuration is the same in our test cases however the content is not the same.

Unfortunately I do not know what delete option was used at the time of the delete. If I happen to get more forensics on this issue I'll provide more details.

acbramley made their first commit to this issue’s fork.

acbramley changed the visibility of the branch 3161212-node-add-gives to hidden.

acbramley’s picture

Title: Node add/edit gives a Call to a member function getAccountName() on null Drupal 11 » Node add/edit gives a Call to a member function getAccountName() on null when author is NULL
Assigned: Unassigned » acbramley
Issue summary: View changes

Working on this, closing previous MR as the branch can't be rebased easily and it was against 11.1.x

acbramley’s picture

Assigned: acbramley » Unassigned
Status: Needs work » Needs review
Issue tags: -Needs tests

It's actually quite difficult to contrive a scenario with core to hit a node add/edit page with a NULL author.

The easiest way for node/add is to override the default value callback to stop setting it to the current user.

I tried to get edit form coverage as well but as soon as you delete the user, the node is gone too because of NodeHooks1::userPredelete

The uid column is non-NULL so we can't update the db directly.

As for wording when the user is missing, I think we can just accept an empty string here hopefully? Seeing as this is quite a rare scenario I think as long as we don't WSOD that's good enough. The author will be set on next save anyway.

acbramley’s picture

Issue summary: View changes
StatusFileSize
new37.57 KB
berdir’s picture

Status: Needs review » Reviewed & tested by the community

What #49 said (and what I said in #41). This shouldn't happen, only thing I can think if is doing things directly in the database and bypassing entity API. (#49 is not quite correcting that regard. You don't need to set it to NULL, that's not what the scenario is about. It's about either setting it to a non-existing UID or deleting said user record without triggering entity hooks).

But I'm not against hardening our code against invalid data. I probably wouldn't even have asked for test coverage but great that you added it anyway.

acbramley’s picture

You don't need to set it to NULL, that's not what the scenario is about. It's about either setting it to a non-existing UID

Tried that and even that's not possible, we have this in Node::preSave

      // If no owner has been set explicitly, make the anonymous user the owner.
      if (!$translation->getOwner()) {
        $translation->setOwnerId(0);
      }

But yeah I agree, this is more than enough :)

smustgrave’s picture

Ran test-only feature

1) Drupal\Tests\node\Functional\NodeEditFormTest::testNodeFormNullAuthor
Behat\Mink\Exception\ExpectationException: Current response status code is 500, but 200 expected.
/builds/issue/drupal-3161212/vendor/behat/mink/src/WebAssert.php:888
/builds/issue/drupal-3161212/vendor/behat/mink/src/WebAssert.php:145
/builds/issue/drupal-3161212/core/modules/node/tests/src/Functional/NodeEditFormTest.php:267
FAILURES!
Tests: 4, Assertions: 105, Failures: 1.

99% of the code is tests so the actual fix makes sense.

Very nice.

  • catch committed b174fb09 on 11.1.x
    Issue #3161212 by joseph.olstad, acbramley, asubit, eduardo morales...

  • catch committed ca57f212 on 11.x
    Issue #3161212 by joseph.olstad, acbramley, asubit, eduardo morales...
catch’s picture

Version: 11.x-dev » 11.1.x-dev
Status: Reviewed & tested by the community » Fixed

Latest MR looks good, no attempt to replace it with something else, just avoid the fatal error.

Committed/pushed to 11.x and cherry-picked to 11.1.x, thanks!

This is eligible for backport to 10.5.x, but we've broken 10.5.x several times recently cherry-picking 11.x commits without a full test run, so marking fixed. If you'd like this to be backported to 10.5.x, feel free to re-open with a 10.5.x-specific MR - it might just need a cherry-pick, but that way we get a full test run before commit.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

logosur’s picture

logosur’s picture

Assigned: Unassigned » logosur
StatusFileSize
new1.14 KB

Added patch to retrieve the author from current user if node is new. This also checks if owner is anonymous.

acbramley’s picture

Assigned: logosur » Unassigned

@logosur $node->getOwner()?->getAccountName() - the ?-> in that is a null safe operator, meaning if getOwner returns NULL it will not call getAccountName.

This content is specifically to show the node's owner/author, we don't need any more logic to show the current user for new nodes as this is set on save automatically. If there's something else you'd like to change then please create a new issue as this one is closed.

sourabhbhalerao’s picture

Got the author issue and patch worked! Thanks

joseph.olstad’s picture

While the faked out null author does cover the use case and is a good test, if someone really wants to go for a ride into wonderland there's possibly an explanation.

Our node bundle has a translated author field and we have two languages.

We also use the ETUF module (entity_translation_unified_form) so both author values are loaded into the same edit page. In our case since the same user edits both languages we probably should have disabled translatability on author. With that said, might explain why it was tricky to write a test.

With that said, our particular case, we should turn off translatability on the author since the same submit button saves two versions of a node (ETUF is amazing)

Still a bit of a mystery, deleting a user somehow missed setting a user reference to anonymous.