Error in Search when upgrading from 3.4 to 3.6

Searching specific pages worked in 3.4 but when upgrading to 3.6 I get the following TypeError:

TypeError thrown with message "Kirby\Cms\Core::{closure}(): Argument #3 ($query) must be of type string, null given, called in /home/wtowersa/public_html/staging.willamettetowers.com/kirby/src/Cms/Search.php on line 40"

Stacktrace:
#12 TypeError in /home/wtowersa/public_html/staging.willamettetowers.com/kirby/config/components.php:140
#11 Kirby\Cms\Core:{closure} in /home/wtowersa/public_html/staging.willamettetowers.com/kirby/src/Cms/Search.php:40

I am searching various pages using a search snippet:

      <form class="formclass">
        <input class="input-enter" type="search" aria-label="Search" name="q" value="<?= html($query) ?>"> <br>
        <input type="submit" value="Search the <?= $page->searchtopic() ?>">
      </form>

        <?php if($query): ?>
          <?php if ($results->count()): ?>
            <ul class="list-group">
              <?php foreach ($results as $result): ?>
                <li class="search-result">
                  <h2><a href="<?= $result->url() ?>"><?= $result->title() ?> / <?= $result->parent()->title() ?></a></h2>
                    <?= getResultText($result->text(), $query) ?>
                </li>
              <?php endforeach ?>
            </ul>
            <?php else: ?>
              <p class="form-result">No results for that entry</p>
          <?php endif ?>
        <?php endif ?>

The controller for one of the pages, specifically the bylaws page:

return function ($site) {

  $query   = get('q');
  $results = page('bylaws')->search($query, 'title|text');

  $results = $results->paginate(20);

  return [
    'query'      => $query,
    'results'    => $results,
    'words'     => true,
    'pagination' => $results->pagination()
  ];
};

The error window shows this from kirby/config/components.php

    'search' => function (
        App $kirby,
        Collection $collection,
        string $query = '',
        $params = []
    ): Collection|bool {
        if (is_string($params) === true) {
            $params = ['fields' => Str::split($params, '|')];
        }

And this includes line 40 from kirby/src/Cms/Search.php

	public static function collection(Collection $collection, string $query = null, $params = [])
	{
		$kirby = App::instance();
		return ($kirby->component('search'))($kirby, $collection, $query, $params);
	}

In version 3.4 those are:

	'search' => function (
        App $kirby, 
        Collection $collection, 
        string $query = null, 
        $params = []) {
		// empty search query
		if (empty(trim($query ?? '')) === true) {
			return $collection->limit(0);
		}

		if (is_string($params) === true) {
			$params = ['fields' => Str::split($params, '|')];
		}

and

	public static function collection(Collection $collection, string $query = null, $params = [])
	{
		$kirby = App::instance();
		return ($kirby->component('search'))($kirby, $collection, $query, $params);
	}

Most of what I know is from perusing the docs and trying things out and I don’t know what I need to correct. Any suggestions are much appreciated.

I know there are newer versions available but I thought I’d focus on the upgrade where I got the changed result.

The error message means that you pass null where a value of type string is expected.

So if $query = get('q') is empty, you get this error. Default to an empty string in this case.

The controller is searching stuff even when the query is not set.
Try searching only if there actually is a query.

return function ($site) {

  $query = get('q');

  if($query) {
    $results = page('bylaws')->search($query, 'title|text');
    $results = $results->paginate(20);
  } else {
    $results = false;
  }

  return [
    'query'      => $query,
    'results'    => $results,
    'words'     => true,
    'pagination' => $results->pagination()
  ];
};

Thanks so much. I entered rasteiner’s code and get this error:

Call to a member function pagination() on bool

Which I understand in concept but don’t know how to correct.

If I remove both pagination statements, search works fine.

If $results is false, you cannot call the pagination() method on it, so have to do this conditionally as well

 'pagination' => $results ? $results->pagination()` : null

But then you have to check in your templates if pagination is an object.

Maybe instead of setting $result to false, better use an empty collection:

  if($query) {
    $results = page('bylaws')->search($query, 'title|text');
    $results = $results->paginate(20);
  } else {
    $results = new Pages();
  }

Sorry, I saw that in the template you wrapped the of use $results in a if($query), so I mistakenly assumed everything would work. texnixe is obviously right, new Pages() is better

Many thanks! You are wonderful people!