Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GraphQL mutations throw internal server error via REST, but succeed via GraphiQL in CraftCMS 3.7.x #9842

Closed
humandevs opened this issue Sep 16, 2021 · 5 comments
Labels

Comments

@humandevs
Copy link

humandevs commented Sep 16, 2021

Description

Sending a GraphQL mutation within GraphiQL succeeds, but when I submit the exact same mutation using the same Schema (with full mutation permissions) via a POST, I get an internal server error.

When sending the mutation via POST it throws the following error in web.log:

2021-09-15 22:47:43 [-][-][-][error][yii\base\ErrorException:8] yii\base\ErrorException: Undefined offset: 19 in /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/helpers/ElementHelper.php:313
Stack trace:
#0 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/web/ErrorHandler.php(75): yii\base\ErrorHandler->handleError(8, 'Undefined offse...', '/srv/app/dci-dg...', 313)
#1 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/helpers/ElementHelper.php(313): craft\web\ErrorHandler->handleError(8, 'Undefined offse...', '/srv/app/dci-dg...', 313, Array)
#2 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/services/Elements.php(2482): craft\helpers\ElementHelper::supportedSitesForElement(Object(craft\elements\Entry))
#3 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/services/Elements.php(783): craft\services\Elements->_saveElementInternal(Object(craft\elements\Entry), true, true, NULL)
#4 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/gql/base/ElementMutationResolver.php(164): craft\services\Elements->saveElement(Object(craft\elements\Entry))
#5 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/gql/resolvers/mutations/Entry.php(51): craft\gql\base\ElementMutationResolver->saveElement(Object(craft\elements\Entry))
#6 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(624): craft\gql\resolvers\mutations\Entry->saveEntry(NULL, Array, Array, Object(GraphQL\Type\Definition\ResolveInfo))
#7 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(550): GraphQL\Executor\ReferenceExecutor->resolveFieldValueOrError(Object(GraphQL\Type\Definition\FieldDefinition), Object(GraphQL\Language\AST\FieldNode), Array, NULL, Object(GraphQL\Type\Definition\ResolveInfo))
#8 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(474): GraphQL\Executor\ReferenceExecutor->resolveField(Object(GraphQL\Type\Definition\ObjectType), NULL, Object(ArrayObject), Array)
#9 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(858): GraphQL\Executor\ReferenceExecutor->GraphQL\Executor\{closure}(Array, 'save_articles_a...')
#10 [internal function]: GraphQL\Executor\ReferenceExecutor->GraphQL\Executor\{closure}(Array, 'save_articles_a...')
#11 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(860): array_reduce(Array, Object(Closure), Array)
#12 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(490): GraphQL\Executor\ReferenceExecutor->promiseReduce(Array, Object(Closure), Array)
#13 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(263): GraphQL\Executor\ReferenceExecutor->executeFieldsSerially(Object(GraphQL\Type\Definition\ObjectType), NULL, Array, Object(ArrayObject))
#14 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(215): GraphQL\Executor\ReferenceExecutor->executeOperation(Object(GraphQL\Language\AST\OperationDefinitionNode), NULL)
#15 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/Executor/Executor.php(156): GraphQL\Executor\ReferenceExecutor->doExecute()
#16 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/GraphQL.php(162): GraphQL\Executor\Executor::promiseToExecute(Object(GraphQL\Executor\Promise\Adapter\SyncPromiseAdapter), Object(GraphQL\Type\Schema), Object(GraphQL\Language\AST\DocumentNode), NULL, Array, Array, 'updateArticleLo...', NULL)
#17 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/GraphQL.php(94): GraphQL\GraphQL::promiseToExecute(Object(GraphQL\Executor\Promise\Adapter\SyncPromiseAdapter), Object(GraphQL\Type\Schema), 'mutation update...', NULL, Array, Array, 'updateArticleLo...', NULL, Array)
#18 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/services/Gql.php(545): GraphQL\GraphQL::executeQuery(Object(GraphQL\Type\Schema), 'mutation update...', NULL, Array, Array, 'updateArticleLo...', NULL, Array)
#19 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/controllers/GraphqlController.php(172): craft\services\Gql->executeQuery(Object(craft\models\GqlSchema), 'mutation update...', Array, 'updateArticleLo...', false)
#20 [internal function]: craft\controllers\GraphqlController->actionApi()
#21 /srv/app/dci-dg-test/htdocs/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)
#22 /srv/app/dci-dg-test/htdocs/vendor/yiisoft/yii2/base/Controller.php(181): yii\base\InlineAction->runWithParams(Array)
#23 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/web/Controller.php(190): yii\base\Controller->runAction('api', Array)
#24 /srv/app/dci-dg-test/htdocs/vendor/yiisoft/yii2/base/Module.php(534): craft\web\Controller->runAction('api', Array)
#25 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/web/Application.php(277): yii\base\Module->runAction('graphql/api', Array)
#26 /srv/app/dci-dg-test/htdocs/vendor/yiisoft/yii2/web/Application.php(104): craft\web\Application->runAction('graphql/api', Array)
#27 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/web/Application.php(262): yii\web\Application->handleRequest(Object(craft\web\Request))
#28 /srv/app/dci-dg-test/htdocs/vendor/yiisoft/yii2/base/Application.php(392): craft\web\Application->handleRequest(Object(craft\web\Request))
#29 /srv/app/dci-dg-test/htdocs/web/index.php(21): yii\base\Application->run()
#30 {main}
2021-09-15 22:47:43 [-][-][-][info][application] $_GET = [
    'p' => 'api'
]

]

Network trace shows the same payload (except obviously some special headers for being sent because GraphiQL is in admin):

The post succeeding in GraphiQL
image

And the response from the server confirming the mutation succeeded via GraphiQL:
image

The POST with the same mutation that is throwing the error:
image

And the response with the internal server error:
image

This didn't happen in 3.5.19, but 3.5 also doesn't have the ability to post to nested Super Table > Matrix fields, which we also need to do here (although this is just a Matrix field).

Note: The POST is using a Bearer token that is assigned to a schema with all boxes checked on the GraphQL schema page. The GraphiQL mutation is also run with the same Schema selected (instead of the default "full" schema GraphiQL uses), to rule out a schema permission issue:
image

Note: I got a different internal server error when attempting to run this mutation via a POST with an older version of the element-api plugin, but that error went away after upgrading that plugin to the latest version.

Note: This is the same CraftCMS instance as was running for for CraftCMS Support ticket # 15025, which should have a zip of the config and database in the ticket, if needed, though that hadn't yet bet upgraded to Craft 3.7.x.

Steps to reproduce

  1. Post a GraphiQL mutation via GraphiQL and confirm mutation returns okay
  2. Post the same GraphiQL mutation via POST and note the mutation throws an internal server error

Additional info

  • Craft version: 3.7.13
  • PHP version: 7.4.15
  • Database driver & version: MySQL 5.7.33
  • Plugins & versions: element-api (2.8.2), super table (dev-craft-3 as 2.6.8),
@brandonkelly
Copy link
Member

Looks like this might be happening due to a disabled site. Just fixed that for the next release.

To get the fix early, change your craftcms/cms requirement in composer.json to "dev-develop as 3.7.13" and run composer update.

@humandevs
Copy link
Author

humandevs commented Sep 16, 2021

dev-develop definitely fixed that error, but now we get an explicit error about the disabled site ja being an invalid site handle. ja is not the site we are trying to mutate, though (we are trying to mutate the default en site), but ja is the only site that is disabled:

2021-09-16 14:52:47 [-][-][-][error][yii\base\InvalidArgumentException] yii\base\InvalidArgumentException: Invalid site handle: ja in /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/elements/db/ElementQuery.php:1010
Stack trace:
#0 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/elements/db/ElementQuery.php(542): craft\elements\db\ElementQuery->site('ja')
#1 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/elements/db/EntryQuery.php(228): craft\elements\db\ElementQuery->__set('site', 'ja')
#2 /srv/app/dci-dg-test/htdocs/vendor/yiisoft/yii2/BaseYii.php(558): craft\elements\db\EntryQuery->__set('site', 'ja')
#3 /srv/app/dci-dg-test/htdocs/vendor/rias/craft-scout/src/models/AlgoliaIndex.php(299): yii\BaseYii::configure(Object(craft\elements\db\EntryQuery), Array)
#4 /srv/app/dci-dg-test/htdocs/vendor/rias/craft-scout/src/models/AlgoliaIndex.php(88): rias\scout\models\AlgoliaIndex->getElementQuery(Object(craft\elements\Entry))
#5 /srv/app/dci-dg-test/htdocs/vendor/rias/craft-scout/src/models/AlgoliaIndex.php(138): rias\scout\models\AlgoliaIndex->canDeindexElement(Object(craft\elements\Entry))
#6 /srv/app/dci-dg-test/htdocs/vendor/rias/craft-scout/src/services/ScoutService.php(121): rias\scout\models\AlgoliaIndex->indexElements(Array)
#7 /srv/app/dci-dg-test/htdocs/vendor/rias/craft-scout/src/Scout.php(161): rias\scout\services\ScoutService->indexElements(Array)
#8 /srv/app/dci-dg-test/htdocs/vendor/rias/craft-scout/src/Scout.php(88): rias\scout\Scout->indexElements(Array)
#9 [internal function]: rias\scout\Scout->rias\scout\{closure}(Object(craft\events\ModelEvent))
#10 /srv/app/dci-dg-test/htdocs/vendor/yiisoft/yii2/base/Event.php(312): call_user_func(Object(Closure), Object(craft\events\ModelEvent))
#11 /srv/app/dci-dg-test/htdocs/vendor/yiisoft/yii2/base/Component.php(637): yii\base\Event::trigger('craft\\base\\Elem...', 'afterSave', Object(craft\events\ModelEvent))
#12 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/base/Element.php(3995): yii\base\Component->trigger('afterSave', Object(craft\events\ModelEvent))
#13 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/elements/Entry.php(1662): craft\base\Element->afterSave(false)
#14 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/services/Elements.php(2678): craft\elements\Entry->afterSave(false)
#15 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/services/Elements.php(783): craft\services\Elements->_saveElementInternal(Object(craft\elements\Entry), true, true, true)
#16 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/gql/base/ElementMutationResolver.php(164): craft\services\Elements->saveElement(Object(craft\elements\Entry))
#17 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/gql/resolvers/mutations/Entry.php(51): craft\gql\base\ElementMutationResolver->saveElement(Object(craft\elements\Entry))
#18 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(624): craft\gql\resolvers\mutations\Entry->saveEntry(NULL, Array, Array, Object(GraphQL\Type\Definition\ResolveInfo))
#19 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(550): GraphQL\Executor\ReferenceExecutor->resolveFieldValueOrError(Object(GraphQL\Type\Definition\FieldDefinition), Object(GraphQL\Language\AST\FieldNode), Array, NULL, Object(GraphQL\Type\Definition\ResolveInfo))
#20 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(474): GraphQL\Executor\ReferenceExecutor->resolveField(Object(GraphQL\Type\Definition\ObjectType), NULL, Object(ArrayObject), Array)
#21 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(858): GraphQL\Executor\ReferenceExecutor->GraphQL\Executor\{closure}(Array, 'save_articles_a...')
#22 [internal function]: GraphQL\Executor\ReferenceExecutor->GraphQL\Executor\{closure}(Array, 'save_articles_a...')
#23 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(860): array_reduce(Array, Object(Closure), Array)
#24 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(490): GraphQL\Executor\ReferenceExecutor->promiseReduce(Array, Object(Closure), Array)
#25 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(263): GraphQL\Executor\ReferenceExecutor->executeFieldsSerially(Object(GraphQL\Type\Definition\ObjectType), NULL, Array, Object(ArrayObject))
#26 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/Executor/ReferenceExecutor.php(215): GraphQL\Executor\ReferenceExecutor->executeOperation(Object(GraphQL\Language\AST\OperationDefinitionNode), NULL)
#27 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/Executor/Executor.php(156): GraphQL\Executor\ReferenceExecutor->doExecute()
#28 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/GraphQL.php(162): GraphQL\Executor\Executor::promiseToExecute(Object(GraphQL\Executor\Promise\Adapter\SyncPromiseAdapter), Object(GraphQL\Type\Schema), Object(GraphQL\Language\AST\DocumentNode), NULL, Array, Array, 'updateArticleLo...', NULL)
#29 /srv/app/dci-dg-test/htdocs/vendor/webonyx/graphql-php/src/GraphQL.php(94): GraphQL\GraphQL::promiseToExecute(Object(GraphQL\Executor\Promise\Adapter\SyncPromiseAdapter), Object(GraphQL\Type\Schema), 'mutation update...', NULL, Array, Array, 'updateArticleLo...', NULL, Array)
#30 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/services/Gql.php(545): GraphQL\GraphQL::executeQuery(Object(GraphQL\Type\Schema), 'mutation update...', NULL, Array, Array, 'updateArticleLo...', NULL, Array)
#31 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/controllers/GraphqlController.php(172): craft\services\Gql->executeQuery(Object(craft\models\GqlSchema), 'mutation update...', Array, 'updateArticleLo...', false)
#32 [internal function]: craft\controllers\GraphqlController->actionApi()
#33 /srv/app/dci-dg-test/htdocs/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)
#34 /srv/app/dci-dg-test/htdocs/vendor/yiisoft/yii2/base/Controller.php(181): yii\base\InlineAction->runWithParams(Array)
#35 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/web/Controller.php(190): yii\base\Controller->runAction('api', Array)
#36 /srv/app/dci-dg-test/htdocs/vendor/yiisoft/yii2/base/Module.php(534): craft\web\Controller->runAction('api', Array)
#37 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/web/Application.php(277): yii\base\Module->runAction('graphql/api', Array)
#38 /srv/app/dci-dg-test/htdocs/vendor/yiisoft/yii2/web/Application.php(104): craft\web\Application->runAction('graphql/api', Array)
#39 /srv/app/dci-dg-test/htdocs/vendor/craftcms/cms/src/web/Application.php(262): yii\web\Application->handleRequest(Object(craft\web\Request))
#40 /srv/app/dci-dg-test/htdocs/vendor/yiisoft/yii2/base/Application.php(392): craft\web\Application->handleRequest(Object(craft\web\Request))
#41 /srv/app/dci-dg-test/htdocs/web/index.php(21): yii\base\Application->run()
#42 {main}
2021-09-16 14:52:46 [-][-][-][info][application] $_GET = [
    'p' => 'api'
]

Edit: For reference, here's what our sites look like:

image

@humandevs
Copy link
Author

Oh, this looks like an issue with craft-scout. Will try updating that plugin...

@brandonkelly
Copy link
Member

Craft 3.7.14 is out now with that initial fix.

@humandevs
Copy link
Author

Note: Updating craft-scout to latest 2.5.0 resolved the issue mentioned previously, but attempting a mutation when a disabled site exists still throws an error in Craft 3.7.14. See: #9948

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants