craftcms / cms

Build bespoke content experiences with Craft.
https://craftcms.com
Other
3.22k stars 625 forks source link

[3.x]: TypeError: Return value of craft\fields\Assets::_findFolder() #13861

Open mtwalsh opened 10 months ago

mtwalsh commented 10 months ago

What happened?

Description

Just updated a Craft CMS 3 site to 3.9.5 and now getting this error when trying to create a new entry:

TypeError: Return value of craft\fields\Assets::_findFolder() must be an instance of craft\models\VolumeFolder, null returned

FWIW the entry type does have a couple of asset fields, which "Restrict assets to a single folder" on Amazon S3 and that asset location does contain {slug} (I wonder if that might be of importance).

I can create new entries in other sections without any problems.

The only slightly awkward point is that I can't reproduce this issue locally, only in production, which is unusual. But given this site isn't under active development and the Craft CMS upgrade is the only change that's been made (this was working just fine a few days ago) I'm a little out of ideas!

Steps to reproduce

  1. Go to a section and hit the "New entry" button.
  2. Get a 500 error.

Stack trace

TypeError: Return value of craft\fields\Assets::_findFolder() must be an instance of craft\models\VolumeFolder, null returned
(/domain.com/vendor/craftcms/cms/src/fields/Assets.php:889)
        return $folder;
craft\fields\Assets::_findFolder(/domain.com/vendor/craftcms/cms/src/fields/Assets.php:947)
            return $this->_findFolder($sourceKey, $subpath, $element, $createDynamicFolders);
craft\fields\Assets::_uploadFolder(/domain.com/vendor/craftcms/cms/src/fields/Assets.php:638)
        $folder = $this->_uploadFolder($element, false);
craft\fields\Assets::inputSources(/domain.com/vendor/craftcms/cms/src/fields/BaseRelationField.php:1008)
            'sources' => $this->inputSources($element),
craft\fields\BaseRelationField::inputTemplateVariables(/domain.com/vendor/craftcms/cms/src/fields/Assets.php:698)
        $variables = parent::inputTemplateVariables($value, $element);
craft\fields\Assets::inputTemplateVariables(/domain.com/vendor/craftcms/cms/src/fields/BaseRelationField.php:594)
        $variables = $this->inputTemplateVariables($value, $element);
craft\fields\BaseRelationField::inputHtml(/domain.com/vendor/craftcms/cms/src/fields/Assets.php:283)
            return parent::inputHtml($value, $element);
craft\fields\Assets::inputHtml(/domain.com/vendor/craftcms/cms/src/base/Field.php:465)
        $html = $this->inputHtml($value, $element);
craft\base\Field::getInputHtml(/domain.com/vendor/craftcms/cms/src/fieldlayoutelements/CustomField.php:260)
        $html = $this->_field->getInputHtml($value, $element);
craft\fieldlayoutelements\CustomField::inputHtml(/domain.com/vendor/craftcms/cms/src/fieldlayoutelements/BaseField.php:203)
        $inputHtml = $this->inputHtml($element, $static);
craft\fieldlayoutelements\BaseField::formHtml(/domain.com/vendor/craftcms/cms/src/fieldlayoutelements/CustomField.php:213)
            return (string)parent::formHtml($element, $static);
craft\fieldlayoutelements\CustomField::craft\fieldlayoutelements\{closure}(/domain.com/vendor/craftcms/cms/src/web/View.php:1529)
            $response = $this->namespaceInputs($html(), $namespace, $otherAttributes, $withClasses);
craft\web\View::namespaceInputs(/domain.com/vendor/craftcms/cms/src/fieldlayoutelements/CustomField.php:214)
        }, 'fields');
craft\fieldlayoutelements\CustomField::formHtml(/domain.com/vendor/craftcms/cms/src/models/FieldLayout.php:594)
                    return (string)$layoutElement->formHtml($element, $static);
craft\models\FieldLayout::craft\models\{closure}(/domain.com/vendor/craftcms/cms/src/web/View.php:1524)
                return $html();
craft\web\View::namespaceInputs(/domain.com/vendor/craftcms/cms/src/models/FieldLayout.php:593)
                $elementHtml = $view->namespaceInputs(function() use ($layoutElement, $element, $static) {
craft\models\FieldLayout::createForm(/domain.com/vendor/twig/twig/src/Extension/CoreExtension.php:1570)
        $ret = $object->$method(...$arguments);
twig_get_attribute(/domain.com/vendor/craftcms/cms/src/helpers/Template.php:106)
            return \twig_get_attribute($env, $source, $object, $item, $arguments, $type, $isDefinedTest, $ignoreStrictCheck);
craft\helpers\Template::attribute(/domain.com/storage/runtime/compiled_templates/cc/ccdeb57a8125a11059a9d998753a3fd8fa9394a42559dec1c7d29839d543e952.php:175)
        $context["form"] = craft\helpers\Template::attribute($this->env, $this->source, craft\helpers\Template::attribute($this->env, $this->source, ($context["element"] ?%3F_null%29%2C_%22getFieldLayout%22%2C_%5B0%5D=%3E+%28%24context%5B%22element%22%5D+%
__TwigTemplate_77a0c1f2083b9dfb852c9a7f66358708c8549cc77bf8ab70910e2ddfc83e2509::doDisplay(/domain.com/vendor/twig/twig/src/Template.php:405)
            $this->doDisplay($context, $blocks);
Twig\Template::displayWithErrorHandling(/domain.com/vendor/twig/twig/src/Template.php:378)
        $this->displayWithErrorHandling($this->env->mergeGlobals($context), array_merge($this->blocks, $blocks));
Twig\Template::display(/domain.com/storage/runtime/compiled_templates/6f/6f077381a6ddf3dcae3da5b6ea2777fefc054070a084d88ebfbf1f2933986d6b.php:124)
        $this->parent->display($context, array_merge($this->blocks, $blocks));
__TwigTemplate_367b54d6e17f226ad63b87287416126ede1b4df71984d3ffd174f3ecde983176::doDisplay(/domain.com/vendor/twig/twig/src/Template.php:405)
            $this->doDisplay($context, $blocks);
Twig\Template::displayWithErrorHandling(/domain.com/vendor/twig/twig/src/Template.php:378)
        $this->displayWithErrorHandling($this->env->mergeGlobals($context), array_merge($this->blocks, $blocks));
Twig\Template::display(/domain.com/vendor/twig/twig/src/Template.php:390)
            $this->display($context);
Twig\Template::render(/domain.com/vendor/twig/twig/src/TemplateWrapper.php:45)
        return $this->template->render($context, \func_get_args()[1] ?%3F_%5B0%5D=
Twig\TemplateWrapper::render(/domain.com/vendor/twig/twig/src/Environment.php:318)
        return $this->load($name)->render($context);
Twig\Environment::render(/domain.com/vendor/craftcms/cms/src/web/View.php:408)
            $output = $this->getTwig()->render($template, $variables);
craft\web\View::renderTemplate(/domain.com/vendor/craftcms/cms/src/web/View.php:461)
            echo $this->renderTemplate($template, $variables);
craft\web\View::renderPageTemplate(/domain.com/vendor/craftcms/cms/src/web/Controller.php:216)
        $this->response->data = $view->renderPageTemplate($template, $variables, $templateMode);
craft\web\Controller::renderTemplate(/domain.com/vendor/craftcms/cms/src/controllers/EntriesController.php:258)
        return $this->renderTemplate('entries/_edit', $variables);
craft\controllers\EntriesController::actionEditEntry(:)

call_user_func_array(/domain.com/vendor/yiisoft/yii2/base/InlineAction.php:57)
        return call_user_func_array([$this->controller, $this->actionMethod], $args);
yii\base\InlineAction::runWithParams(/domain.com/vendor/yiisoft/yii2/base/Controller.php:178)
            $result = $action->runWithParams($params);
yii\base\Controller::runAction(/domain.com/vendor/yiisoft/yii2/base/Module.php:552)
            $result = $controller->runAction($actionID, $params);
yii\base\Module::runAction(/domain.com/vendor/craftcms/cms/src/web/Application.php:295)
        $result = parent::runAction($route, $params);
craft\web\Application::runAction(/domain.com/vendor/yiisoft/yii2/web/Application.php:103)
            $result = $this->runAction($route, $params);
yii\web\Application::handleRequest(/domain.com/vendor/craftcms/cms/src/web/Application.php:280)
            return parent::handleRequest($request);
craft\web\Application::handleRequest(/domain.com/vendor/yiisoft/yii2/base/Application.php:384)
            $response = $this->handleRequest($this->getRequest());
yii\base\Application::run(/sites/domain.com/public/index.php:26)
$app->run();

Craft CMS version

3.9.5

PHP version

7.3.33

Operating system and version

Ubuntu 20.04

Database type and version

MySQL 5.7

Image driver and version

No response

Installed plugins and versions

Plugin Version
Amazon S3 1.3.2
Asset Rev 6.0.2
Embedded Assets 2.11.4
Expanded Singles 1.2.0
Image Resizer 2.2.2
Maps 3.9.4
MatrixMate 1.5.0
Phone Number 1.5.0
Redactor 2.10.12
Rollbar 1.0.3
SEO 3.4.62
Super Table 2.7.5.1
Typed link field 2.0.0-rc.2
Webhooks 2.4.1
mtwalsh commented 10 months ago

I did try backtracking some updates to no avail so ended up resolving the issue by upgrading to Craft 4 and moving to another server environment with PHP8. It's possible there may still be an issue here with dynamic S3 folders via the entry {slug}.

michaelrog commented 7 months ago

I ran into this exact issue as well — also Craft 3.9.10, with an S3 volume and a restricted upload path of {slug}.

@brandonkelly wanna re-open this one, or should I start a new thread?

brandonkelly commented 7 months ago

@michaelrog Craft 3 is only getting security fixes at this point.

mtwalsh commented 7 months ago

I ended up having to abandon the whole dynamic asset location approach (containing {slug}) altogether as even after upgrading to Craft 4 the original problem above still persisted.

brandonkelly commented 7 months ago

@mtwalsh Ah ok, thanks for the clarification. I thought you were saying the Craft 4 upgrade resolved it, since you closed the issue.

mtwalsh commented 7 months ago

Sorry @brandonkelly, that's exactly what I thought had happened - it was fixed with the Craft 4 upgrade. But then it cropped up again and as I still only had the issue in production (load-balanced AWS) and it was preventing our client from getting things published on their site I had to act quickly and just take an different approach rather than get to the bottom it. I can't say we use dynamic asset locations with S3 on many projects at all so wondered if it might just be safer to abandon that approach.

mtwalsh commented 7 months ago

I did hint there may still be unfinished business!

It's possible there may still be an issue here with dynamic S3 folders via the entry {slug}

But I didn't want anyone to invest time looking into something that might just be related to our particular hosting setup, but now someone else has hit the same issue maybe it's not just us!

Happy to help, if I can.

michaelrog commented 7 months ago

fwiw, in our case, this error appears on initial creation. If we immediately refresh the edit page, everything loads fine. Could just be that the slug variable isn't initialized yet by the time _findFolder() needs it?

mtwalsh commented 7 months ago

@michaelrog Yes, same here initial creation but if memory serves, we had issues thereafter on save as well - or at least the images didn't make it to where they should have.