With a product variation with a null store and the PriceCalculatedFormatter, I got this error:
TypeError: Argument 2 passed to Drupal\commerce\Context::__construct() must implement interface Drupal\commerce_store\Entity\StoreInterface, null given, called in modules/order/src/Plugin/Field/FieldFormatter/PriceCalculatedFormatter.php on line 177 in Drupal\commerce\Context->__construct() (line 46 of modules/contrib/commerce/src/Context.php).

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

edurenye created an issue. See original summary.

TwiiK’s picture

I get the same error. I upgraded to 2.4 for this exact functionality and it doesn't seem to work.

What do you mean with this:

With a product variation with a null store[...]

What's a "null store"? Does that mean you know how how to trigger this error and how to avoid it? I'm on what I assume is a fairly default Commerce setup and I have no idea how to avoid this error or what it means to have a "null store" on a product variation.

Edit: I'm very new to Drupal 8 and OOP in PHP in general so I'm just flailing wildly here, but I assume $store in this example should contain something and not be empty?

$container = Drupal::getContainer();
$current_store = $container->get('commerce_store.current_store');
$store = $current_store->getStore();

I don't really know what it should contain or how it expects to be populated because I don't comprehend the code.

By looking through the admin interface I don't understand how you set a default store and I assume this problem is because I have no default store assigned, but in that case I'd expect nothing to work?

Edit2: I found the checkbox for assigning a default store now. It's on the store edit screen, but it's greyed out and checked because I only have one store so I guess that solves that small mystery. :p

bojanz’s picture

Commerce can't work without a default store. That's why we disable product add/edit forms when there are no stores.
If you have products, but no stores, then your system is in a broken state.

Go to admin/commerce/config/stores and create a store. If there's one already, edit it and select the "Default" checkbox.
Then resave your products.

TwiiK’s picture

It worked for me after adding a second store. I noted that the "Default" checkbox was checked by default and greyed out even though I was adding a second store, as if Commerce didn't recognize my first store. After I added the second store I could assign my original store to be default again and delete the second store.

I exported my config to see what had changed and default_store was changed in commerce_store.settings.yml even though it actually shouldn't have been. I guess there was something iffy about my config.

But I assure you everything has worked on this site up until this point. I've been adding products, completing checkouts, fulfilling orders etc.

Either way, it works now. Thanks.

Edit: Ohh, and the price formatter works as expected. I can see the promotions on the product page now. Thumbs up!

bojanz’s picture

Title: Error with null store with PriceCalculatedFormatter » The default store is sometimes not set

The problem is that the default store UUID is stored in config, so a config (re)deploy can break that connection. A site then has a store, but the default store is not set.

We need to remove the default_store config key, and replace it with an isDefault() flag on the stores themselves.

We should also think about introducing a potential fallback / healing code (if no default store is set, and there is a single store entity, promote it to default)

zenimagine’s picture

dionsj’s picture

I took a rough grab at how they fixed it in commerce_marketplace, as linked to by zenimagine.
The patch is likely very rough, but does seem to fix the issue for me locally, so if anyone else if willing to test that would be nice.

oldspot’s picture

I just experienced the same error while trying to view a product which was working fine up until now.

After reading comment #5 I just realised that beforehand I had done a feature revert which had some commerce changes, so I have gone into the default store edit page and hit Save without changing any values.

The product page loaded fine afterwards without any errors.

If this happens again after a feature revert I will give the patch a test.

drugan’s picture

The reason why some people see their store default checkbox checked and even disabled and at the same time have no-default-store errors is that when you had a default store before but then it is disappeared (deleted, feature revert, etc.,), so, wnenever and whichever store edit page you'll visit then this checkbox will be checked for you (the same as when you create the very first store on a site).

The solution is simple: just resave any desired store as it was noticed by @oldspot and the default store will appear internally in config settings, not only visually on a store edit form.

Another solution is just install the https://www.drupal.org/project/commerce_marketplace and additionally to the fixed no-default-store error you'll get a bunch of other useful features. Even if you don't use marketplace strategy. Particularly, I'd recommend to review the admin/commerce/config/stores and admin/commerce/products views provided by the module.

Londova’s picture

I have the same problem; The patch #7 doesn't help.
(I am not able to Remove Orders).

John Pitcairn’s picture

In my case the user role needed to be granted the permission "Online: View stores". This permission check appears to be new since 2.11 or so?

joekers’s picture

We had users who were getting this error when trying to add a promotion. Granting the ""Online: View stores" permission fixed this.

firfin’s picture

FileSize
78.74 KB

For me the solution was to do the 'add a second store, set as default, set first as default, delete second store' trick from #4, thanks Twiik!
Also afterwards in the product type's manage form display settings set the stores field to entity select, following the hint / clatification by Bojanz in #2865233: Provide a more precise error message when a malformed product references no stores #8. Many thanks also.

ljgra’s picture

#12 is what worked for me. Thanks!

handkerchief’s picture

#12 was the reason for me too. Thank you!

manuel.adan’s picture

Component: Order » Store
Priority: Normal » Major
FileSize
1.5 KB

#5 is right. There is a reference in config to a piece of content, which is a clear bug. The patch is just a workaround that I added to one project. I changed the priority to Major since we have an error in all product pages after a simple config update.

bradjones1’s picture

Title: The default store is sometimes not set » Remove the default_store config key, replace it with isDefault() flag

Updating title to reflect action item per maintainer comment.

czigor’s picture

The attached patch removes the whole commerce_store simple config (since default_store is the only key it contains) and adds an is_default base field to the store entity. Falls back to the first store found when there's no default store.

Basically I copied the default profile logic.

No test added.

Status: Needs review » Needs work

The last submitted patch, 18: commerce-2945939-default_store-18.patch, failed testing. View results

czigor’s picture

Status: Needs work » Needs review
FileSize
9.58 KB
646 bytes

No access check needed for default store.

Status: Needs review » Needs work

The last submitted patch, 20: commerce-2945939-default_store-20.patch, failed testing. View results

czigor’s picture

Status: Needs work » Needs review
FileSize
10.11 KB
939 bytes

Removing a line that should be unnecessary but changes our store entity object a bit.
(Instead of $store->values['is_default'] = ['x-default' => 1] we have $store->values['is_default'] = [0 => ['x-default' => true]].)

Status: Needs review » Needs work

The last submitted patch, 22: commerce-2945939-default_store-22.patch, failed testing. View results

czigor’s picture

Status: Needs work » Needs review
FileSize
10.79 KB
554 bytes

Same issue as before. Let's reload stores before using them to make sure is_default field is in the correct format.

bojanz’s picture

Assigned: Unassigned » bojanz
Status: Needs review » Needs work

Patch no longer applies, needs a reroll. The update functions also need to be renumbered.

+      // The store was set as default, remove the flag from other stores.
+      $store_ids = $storage->getQuery()
+        ->condition('is_default', TRUE)
+        ->execute();
+      if ($store_ids) {
+        foreach ($store_ids as $store_id) {
+          if ($store_id != $this->id()) {
+            $storage->load($store_id)
+              ->setDefault(FALSE)
+              ->save();
+          }
+        }
+      }

We can filter out the current store ID in the query.
Also, this query is missing accessCheck(FALSE).

   public function loadDefault() {
-    $default = NULL;
-    $uuid = $this->configFactory->get('commerce_store.settings')->get('default_store');
-    if ($uuid) {
-      $entities = $this->loadByProperties(['uuid' => $uuid]);
-      $default = reset($entities);
+    $store_ids = $this->getQuery()
+      ->condition('is_default', TRUE)
+      ->accessCheck(FALSE)
+      ->execute();
+    if ($store_ids) {
+      return $this->load(reset($store_ids));
     }
-
-    return $default;
+    // In case there are no default stores, fall back on the first store.
+    $store_ids = $this->getQuery()
+      ->accessCheck(FALSE)
+      ->execute();
+    if ($store_ids) {
+      return $this->load(reset($store_ids));
+    }

The main query and the fallback query can be merged into one.

   /**
    * {@inheritdoc}
    */
   public function markAsDefault(StoreInterface $store) {

We need to deprecate this method and remove its usages.

+    $fields['is_default'] =  BaseFieldDefinition::create('boolean')
+      ->setLabel(t('Default'))
+      ->setDescription(t('Whether this is the default store.'))
+      ->setDefaultValue(FALSE)
+      ->setDisplayConfigurable('form', TRUE);

Needs a default widget. This will allow us to remove the custom one from StoreForm.

bojanz’s picture

Status: Needs work » Needs review
FileSize
22.63 KB

Addressing my own feedback.

Added a kernel test for the Store entity, we were missing one completely.

bojanz’s picture

Fixing ProductBrowserTestBase.

bojanz’s picture

Status: Needs review » Fixed

Committed.

  • bojanz committed 75ffc46 on 8.x-2.x authored by czigor
    Issue #2945939 by czigor, bojanz, dion-jensen, manuel.adan, firfin:...
zenimagine’s picture

@bojanz I just updated the module but the database refuses to update :

ubuntu@dev-example-com /var/www/www--com $ drush updatedb
 ---------------- ----------- ------------- ---------------------------------- 
  Module           Update ID   Type          Description                       
 ---------------- ----------- ------------- ---------------------------------- 
  commerce_store   4           post-update   Set the default store and remove  
                                             the default_store config key.     
 ---------------- ----------- ------------- ---------------------------------- 


 Do you wish to run the specified pending updates? (yes/no) [yes]:
 > 

>  [notice] Update started: commerce_store_post_update_4
>  [error]  Error: Call to a member function setDefault() on bool in commerce_store_post_update_4() (line 115 of /var/www/www-example-com/web/modules/contrib/commerce/modules/store/commerce_store.post_update.php) #0 /var/www/www-s1biose-com/vendor/drush/drush/src/Commands/core/UpdateDBCommands.php(308): commerce_store_post_update_4(Array)
> #1 /var/www/www-example-com/vendor/drush/drush/includes/batch.inc(251): Drush\Commands\core\UpdateDBCommands::updateDoOnePostUpdate('commerce_store_...', Object(DrushBatchContext))
> #2 /var/www/www-example-com/vendor/drush/drush/includes/batch.inc(196): _drush_batch_worker()
> #3 /var/www/www-example-com/vendor/drush/drush/includes/batch.inc(99): _drush_batch_command('16529')
> #4 /var/www/www-example-com/vendor/drush/drush/src/Commands/core/UpdateDBCommands.php(166): drush_batch_command('16529')
> #5 [internal function]: Drush\Commands\core\UpdateDBCommands->process('16529', Array)
> #6 /var/www/www-example-com/vendor/consolidation/annotated-command/src/CommandProcessor.php(257): call_user_func_array(Array, Array)
> #7 /var/www/www-example-com/vendor/consolidation/annotated-command/src/CommandProcessor.php(212): Consolidation\AnnotatedCommand\CommandProcessor->runCommandCallback(Array, Object(Consolidation\AnnotatedCommand\CommandData))
> #8 /var/www/www-example-com/vendor/consolidation/annotated-command/src/CommandProcessor.php(176): Consolidation\AnnotatedCommand\CommandProcessor->validateRunAndAlter(Array, Array, Object(Consolidation\AnnotatedCommand\CommandData))
> #9 /var/www/www-example-com/vendor/consolidation/annotated-command/src/AnnotatedCommand.php(302): Consolidation\AnnotatedCommand\CommandProcessor->process(Object(Symfony\Component\Console\Output\ConsoleOutput), Array, Array, Object(Consolidation\AnnotatedCommand\CommandData))
> #10 /var/www/www-example-com/vendor/symfony/console/Command/Command.php(255): Consolidation\AnnotatedCommand\AnnotatedCommand->execute(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
> #11 /var/www/www-example-com/vendor/symfony/console/Application.php(1000): Symfony\Component\Console\Command\Command->run(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
> #12 /var/www/www-example-com/vendor/symfony/console/Application.php(255): Symfony\Component\Console\Application->doRunCommand(Object(Consolidation\AnnotatedCommand\AnnotatedCommand), Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
> #13 /var/www/www-example-com/vendor/symfony/console/Application.php(148): Symfony\Component\Console\Application->doRun(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
> #14 /var/www/www-example-com/vendor/drush/drush/src/Runtime/Runtime.php(118): Symfony\Component\Console\Application->run(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
> #15 /var/www/www-example-com/vendor/drush/drush/src/Runtime/Runtime.php(49): Drush\Runtime\Runtime->doRun(Array, Object(Symfony\Component\Console\Output\ConsoleOutput))
> #16 /var/www/www-example-com/vendor/drush/drush/drush.php(72): Drush\Runtime\Runtime->run(Array)
> #17 /var/www/www-example-com/vendor/drush/drush/includes/preflight.inc(18): require('/var/www/www-s1...')
> #18 phar:///usr/local/bin/drush/bin/drush.php(141): drush_main()
> #19 /usr/local/bin/drush(10): require('phar:///usr/loc...')
> #20 {main}. 
> Error: Call to a member function setDefault() on bool in /var/www/www-example-com/web/modules/contrib/commerce/modules/store/commerce_store.post_update.php on line 115 #0 /var/www/www-example-com/vendor/drush/drush/src/Commands/core/UpdateDBCommands.php(308): commerce_store_post_update_4(Array)
> #1 /var/www/www-example-com/vendor/drush/drush/includes/batch.inc(251): Drush\Commands\core\UpdateDBCommands::updateDoOnePostUpdate('commerce_store_...', Object(DrushBatchContext))
> #2 /var/www/www-s1biose-com/vendor/drush/drush/includes/batch.inc(196): _drush_batch_worker()
> #3 /var/www/www-s1biose-com/vendor/drush/drush/includes/batch.inc(99): _drush_batch_command('16529')
> #4 /var/www/www-s1biose-com/vendor/drush/drush/src/Commands/core/UpdateDBCommands.php(166): drush_batch_command('16529')
> #5 [internal function]: Drush\Commands\core\UpdateDBCommands->process('16529', Array)
> #6 /var/www/www-s1biose-com/vendor/consolidation/annotated-command/src/CommandProcessor.php(257): call_user_func_array(Array, Array)
> #7 /var/www/www-s1biose-com/vendor/consolidation/annotated-command/src/CommandProcessor.php(212): Consolidation\AnnotatedCommand\CommandProcessor->runCommandCallback(Array, Object(Consolidation\AnnotatedCommand\CommandData))
> #8 /var/www/www-example-com/vendor/consolidation/annotated-command/src/CommandProcessor.php(176): Consolidation\AnnotatedCommand\CommandProcessor->validateRunAndAlter(Array, Array, Object(Consolidation\AnnotatedCommand\CommandData))
> #9 /var/www/www-example-com/vendor/consolidation/annotated-command/src/AnnotatedCommand.php(302): Consolidation\AnnotatedCommand\CommandProcessor->process(Object(Symfony\Component\Console\Output\ConsoleOutput), Array, Array, Object(Consolidation\AnnotatedCommand\CommandData))
> #10 /var/www/www-example-com/vendor/symfony/console/Command/Command.php(255): Consolidation\AnnotatedCommand\AnnotatedCommand->execute(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
> #11 /var/www/www-example-com/vendor/symfony/console/Application.php(1000): Symfony\Component\Console\Command\Command->run(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
> #12 /var/www/www-example-com/vendor/symfony/console/Application.php(255): Symfony\Component\Console\Application->doRunCommand(Object(Consolidation\AnnotatedCommand\AnnotatedCommand), Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
> #13 /var/www/www-example-com/vendor/symfony/console/Application.php(148): Symfony\Component\Console\Application->doRun(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
> #14 /var/www/www-example-com/vendor/drush/drush/src/Runtime/Runtime.php(118): Symfony\Component\Console\Application->run(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
> #15 /var/www/www-example-com/vendor/drush/drush/src/Runtime/Runtime.php(49): Drush\Runtime\Runtime->doRun(Array, Object(Symfony\Component\Console\Output\ConsoleOutput))
> #16 /var/www/www-example-com/vendor/drush/drush/drush.php(72): Drush\Runtime\Runtime->run(Array)
> #17 /var/www/www-example-com/vendor/drush/drush/includes/preflight.inc(18): require('/var/www/www-s1...')
> #18 phar:///usr/local/bin/drush/bin/drush.php(141): drush_main()
> #19 /usr/local/bin/drush(10): require('phar:///usr/loc...')
> #20 {main}
>  [warning] Drush command terminated abnormally. Check for an exit() in your Drupal site.

In ProcessBase.php line 188:
                                                                                                                                           
  Unable to decode output into JSON: Syntax error                                                                                          
                                                                                                                                           
  Error: Call to a member function setDefault() on bool in commerce_store_post_update_4() (line 115 of /var/www/www-example-com/web/modul  
  es/contrib/commerce/modules/store/commerce_store.post_update.php).                                                                       
                                                                                                                                           

updatedb [--cache-clear [CACHE-CLEAR]] [--entity-updates] [--post-updates [POST-UPDATES]] [--no-cache-clear] [--no-post-updates] [-h|--help] [-q|--quiet] [-v|vv|vvv|--verbose] [-V|--version] [--ansi] [--no-ansi] [-n|--no-interaction] [-d|--debug] [-y|--yes] [--no] [--remote-host REMOTE-HOST] [--remote-user REMOTE-USER] [-r|--root ROOT] [-l|--uri URI] [--simulate] [--pipe] [-D|--define DEFINE] [--xh-link XH-LINK] [--druplicon] [--notify [NOTIFY]] [--] <command>

  • bojanz committed 624e064 on 8.x-2.x
    Issue #2945939 followup: Guard against unloadable stores in the update...
bojanz’s picture

Pushed a followup for #30.

zenimagine’s picture

Thank you I managed to update

Status: Fixed » Closed (fixed)

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