Problem/Motivation

When using the AI Search Block as anonymous user, an error is thrown instead of showing the result.

Steps to reproduce

  • Install and configure the module as instructed in the docs.
  • Enable "Content access" processor.
  • In my case I'm using Pinecone as VDB and Gemini as provider. But that's probably not relevant.
  • Make a search as anonymous user.

Proposed resolution

Not sure what's the best solution here, but the error is due to the fact that $entity_type is NULL due to $field->getDatasourceId() being NULL in method AiVdbProviderClientBase::isMultiple() for field "search_api_node_grants".

Backtrace

#0 /app/docroot/modules/contrib/ai_search_block/src/AiSearchBlockHelper.php(176): Drupal\ai_search_block\AiSearchBlockHelper->getRagResults(Array, 'Where can I ska...')
#1 /app/docroot/modules/contrib/ai_search_block/src/Controller/AiSearchBlockController.php(101): Drupal\ai_search_block\AiSearchBlockHelper->searchRagAction('Where can I ska...')
#2 [internal function]: Drupal\ai_search_block\Controller\AiSearchBlockController->search(Object(Symfony\Component\HttpFoundation\Request))
#3 /app/docroot/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#4 /app/docroot/core/lib/Drupal/Core/Render/Renderer.php(638): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#5 /app/docroot/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(121): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#6 /app/docroot/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#7 /app/vendor/symfony/http-kernel/HttpKernel.php(181): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#8 /app/vendor/symfony/http-kernel/HttpKernel.php(76): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#9 /app/docroot/core/lib/Drupal/Core/StackMiddleware/Session.php(53): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#10 /app/docroot/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#11 /app/docroot/core/lib/Drupal/Core/StackMiddleware/ContentLength.php(28): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#12 /app/docroot/core/modules/big_pipe/src/StackMiddleware/ContentLength.php(32): Drupal\Core\StackMiddleware\ContentLength->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#13 /app/docroot/core/modules/page_cache/src/StackMiddleware/PageCache.php(116): Drupal\big_pipe\StackMiddleware\ContentLength->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#14 /app/docroot/core/modules/page_cache/src/StackMiddleware/PageCache.php(90): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#15 /app/docroot/core/modules/ban/src/BanMiddleware.php(50): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#16 /app/docroot/modules/contrib/shield/src/ShieldMiddleware.php(263): Drupal\ban\BanMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#17 /app/docroot/modules/contrib/shield/src/ShieldMiddleware.php(130): Drupal\shield\ShieldMiddleware->bypass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#18 /app/docroot/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\shield\ShieldMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#19 /app/docroot/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#20 /app/docroot/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php(36): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#21 /app/docroot/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php(51): Drupal\Core\StackMiddleware\AjaxPageState->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#22 /app/docroot/core/lib/Drupal/Core/DrupalKernel.php(741): Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#23 /app/docroot/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#24 {main}
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

jmoreira created an issue. See original summary.

jmoreira’s picture

Issue summary: View changes
wouters_f’s picture

Have you tried emptying the vector db and re-indexing?
I can look into this later this week.

jmoreira’s picture

I have reindexed it multiple times and the issue persists. I could be wrong, but it seems that node access data isn't being indexed, so when the processor tries to use it, there's a problem.

wouters_f’s picture

I've defaulted to no access check as you are absolutely right.

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

jorgik’s picture

Status: Active » Needs review

Faced with an unrelated crash—TypeError from Html::escape(null) during entity rendering in fullEntityCheck().

The crash originates in fullEntityCheck() in AiSearchBlockHelper.php. When a matched entity is rendered via $this->renderer->render(), any field whose referenced entity has corrupt or missing data can cause TypeError. Because there is no error boundary around the render call, the exception
bubbles all the way up and kills the entire search response with a 500.

Proposed solution:

Wrapped the full render-to-markdown block in try { } catch (\Throwable $e). On failure, a watchdog warning is logged with the entity type, ID, and exception message, and the loop continues with the remaining entities. Skipping one broken entity is always preferable to crashing the response for the end user.

The render_mode === 'chunks' path is not affected — it reads pre-rendered chunk strings, not full entity views.

How to reproduce / verify

1. Enable the AI Search Block.
2. Create a taxonomy term with title = NULL (or reference a deleted term in a field on a node).
3. Perform a search that matches the node with the broken reference.
4. Before fix: 500 / TypeError in Html::escape().
5. After fix: Search response is returned normally; watchdog shows a warning for the skipped entity; all other entities are included.

jorgik changed the visibility of the branch 3527930-error-when-using to hidden.

  • wouters_f committed ad2fdfd6 on 2.0.x authored by jorgik
    Revert "Issue #3527930: Guard against empty/null AI provider in...

  • wouters_f committed e3d1b057 on 2.0.x authored by jorgik
    Issue #3527930: Guard against empty/null AI provider in fullEntityCheck...

  • wouters_f committed b92d3c2f on 2.0.x authored by jorgik
    Issue #3527930: Guard entity rendering against TypeError in...
wouters_f’s picture

Status: Needs review » Fixed

Merged into 2.0
Thanks for your help!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

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