Page MenuHomePhabricator

Phabricator workboard import: Array for %Ls conversion is empty. Query: projectPHID IN (%Ls)
Closed, ResolvedPublicBUG REPORT

Description

Upstream: https://we.phorge.it/T16068

Reporting for @kostajh via chat.

when I try to import columns from a workboard when setting up the new sprint workboard, I get this error Array for %Ls conversion is empty. Query: projectPHID IN (%Ls) which shows up somewhere else in Phab indicating lack of permissions

image.png (532×846 px, 49 KB)

So, I was able to locate the sprint name Trust and Safety Product Sprint (Sprint Chocolate Cake (March 24 - April 11)) by searching for "trust and safety cho". But if I enter "chocolate" I can get an error 🍫

I was able to create a new milestone and import that workboard's columns to that milestone. I'm curious what it means "if I enter 'chocolate' I can get an error"— @kostajh can you elaborate what you tried?

Event Timeline

In case it's useful while digging through logs, quotes above are from 2025-04-11 14:55 UTC.

Aklapper changed the task status from Open to Stalled.Apr 17 2025, 3:45 PM

I cannot find anything in Logstash around that time stamp: https://logstash.wikimedia.org/goto/6f368b254e35ed867e3bb48c9887a230 (the error message itself is not an uncommon error, so I'd love to look at a stacktrace).
There is a tiny chance that T389638 may have had some impact but apart from that no recent changes coming immediately to my mind.

I don't understand "if I enter 'chocolate' I can get an error".
The "Type a project name..." field in the "Import Columns - Choose a project to import columns from:" dialog is an autocomplete field; if the search does not return results (it does not for "Chocolate" which would be a search code issue) then you cannot select a project and cannot get an error. In theory.
Or is this about clicking the "Import" button without anything in the "Type a project name..." field?
A clear list of steps, action by action, would be very welcome. )

Unfortunately closing this Phabricator task as no further information has been provided.

@kostajh: After you have provided the information asked for and if this still happens, please set the status of this task back to "Open" via the Add Action...Change Status dropdown. Thanks!

phab issue.gif (726×1 px, 494 KB)

Does this help?

There are two issues AFAICT:

  • In the first step, entering the search term "chocolate" should match a sprint name which has "Chocolate cake", but no result is found
  • in the second step, after clicking the magnifying glass, entering the search term "chocolate" (to find the sprint name with the phrase "chocolate cake") results in the error in the task description
Aklapper changed the subtype of this task from "Task" to "Bug Report".May 6 2025, 12:49 PM

In the first step, entering the search term "chocolate" should match a sprint name which has "Chocolate cake", but no result is found

I vaguely remember something about search failing when it's the second token in a string but don't remember where. In any case, that would be a separate bug for Phabricator (Search).

in the second step, after clicking the magnifying glass, entering the search term "chocolate" (to find the sprint name with the phrase "chocolate cake") results in the error in the task description

Thanks. I can reproduce now in production going to random https://phabricator.wikimedia.org/project/board/7778/import/ and clicking the magnifier button and typing. Interesting that this isn't in the server logs. The error is triggered pretty low-level in /src/infrastructure/storage/xsprintf/qsprintf.php so would be easier to debug by having a stacktrace. :-/

Aklapper triaged this task as Medium priority.
Aklapper edited projects, added Phabricator (Upstream), Upstream; removed Phabricator.
[2025-05-12 14:31:14] EXCEPTION: (AphrontParameterQueryException) Array for %Ls conversion is empty. Query: projectPHID IN (%Ls) at [<phorge>/src/infrastructure/storage/xsprintf/qsprintf.php:383]
arcanist(head=master, ref.master=29575b4f9187), phorge(head=master, ref.master=1f19cbf7486a)
  #0 <#2> qsprintf_check_type(array, string, string) called at [<phorge>/src/infrastructure/storage/xsprintf/qsprintf.php:155]
  #1 <#2> xsprintf_query(array, string, integer, array, integer) called at [<arcanist>/src/xsprintf/xsprintf.php:82]
  #2 <#2> xsprintf(string, array, array) called at [<phorge>/src/infrastructure/storage/xsprintf/PhutilQueryString.php:25]
  #3 <#2> PhutilQueryString::__construct(AphrontMySQLiDatabaseConnection, array) called at [<phorge>/src/infrastructure/storage/xsprintf/qsprintf.php:78]
  #4 <#2> qsprintf(AphrontMySQLiDatabaseConnection, string, array) called at [<phorge>/src/applications/project/query/PhabricatorProjectColumnQuery.php:189]
  #5 <#2> PhabricatorProjectColumnQuery::buildWhereClauseParts(AphrontMySQLiDatabaseConnection) called at [<phorge>/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php:505]
  #6 <#2> PhabricatorCursorPagedPolicyAwareQuery::buildWhereClause(AphrontMySQLiDatabaseConnection) called at [<phorge>/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php:328]
  #7 <#2> PhabricatorCursorPagedPolicyAwareQuery::buildStandardPageQuery(AphrontMySQLiDatabaseConnection, string) called at [<phorge>/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php:302]
  #8 <#2> PhabricatorCursorPagedPolicyAwareQuery::loadStandardPageRowsWithConnection(AphrontMySQLiDatabaseConnection, string) called at [<phorge>/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php:293]
  #9 <#2> PhabricatorCursorPagedPolicyAwareQuery::loadStandardPageRows(PhabricatorProjectColumn) called at [<phorge>/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php:287]
  #10 <#2> PhabricatorCursorPagedPolicyAwareQuery::loadStandardPage(PhabricatorProjectColumn) called at [<phorge>/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php:283]
  #11 <#2> PhabricatorCursorPagedPolicyAwareQuery::loadPage() called at [<phorge>/src/infrastructure/query/policy/PhabricatorPolicyAwareQuery.php:251]
  #12 <#2> PhabricatorPolicyAwareQuery::execute() called at [<phorge>/src/applications/project/typeahead/PhabricatorProjectDatasource.php:59]
  #13 <#2> PhabricatorProjectDatasource::loadResults() called at [<phorge>/src/applications/typeahead/datasource/PhabricatorTypeaheadDatasource.php:142]
  #14 <#2> PhabricatorTypeaheadDatasource::loadResultsForPhase(string, integer) called at [<phorge>/src/applications/typeahead/datasource/PhabricatorTypeaheadCompositeDatasource.php:136]
  #15 <#2> PhabricatorTypeaheadCompositeDatasource::loadResultsForPhase(string, integer) called at [<phorge>/src/applications/typeahead/datasource/PhabricatorTypeaheadCompositeDatasource.php:48]
  #16 <#2> PhabricatorTypeaheadCompositeDatasource::loadResults() called at [<phorge>/src/applications/typeahead/controller/PhabricatorTypeaheadModularDatasourceController.php:91]
  #17 <#2> PhabricatorTypeaheadModularDatasourceController::handleRequest(AphrontRequest) called at [<phorge>/src/aphront/configuration/AphrontApplicationConfiguration.php:284]
  #18 phlog(AphrontParameterQueryException) called at [<phorge>/src/aphront/handler/PhabricatorAjaxRequestExceptionHandler.php:27]
  #19 PhabricatorAjaxRequestExceptionHandler::handleRequestThrowable(AphrontRequest, AphrontParameterQueryException) called at [<phorge>/src/aphront/configuration/AphrontApplicationConfiguration.php:753]
  #20 AphrontApplicationConfiguration::handleThrowable(AphrontParameterQueryException) called at [<phorge>/src/aphront/configuration/AphrontApplicationConfiguration.php:296]
  #21 AphrontApplicationConfiguration::processRequest(AphrontRequest, PhutilDeferredLog, AphrontPHPHTTPSink, MultimeterControl) called at [<phorge>/src/aphront/configuration/AphrontApplicationConfiguration.php:203]
  #22 AphrontApplicationConfiguration::runHTTPRequest(AphrontPHPHTTPSink) called at [<phorge>/webroot/index.php:35]

I was initially looking at the SQL query being something like

SELECT `project`.* FROM `project` `project`  WHERE (((`project`.spacePHID IN ([...]) OR `project`.spacePHID IS NULL)) AND ((project.name LIKE 'choco%')))   ORDER BY `project`.`status` ASC, `project`.`id` DESC LIMIT 101

and was thinking of replacing project.name LIKE 'choco%' OR project.name LIKE '% choco%' in PhabricatorProjectQuery to mitigate the search result issue:

         $parts[] = qsprintf(
           $conn,
-          'project.name LIKE %>',
-          $name_prefix);
+          'project.name LIKE %> OR project.name LIKE %~',
+          $name_prefix,
+          ' '.$name_prefix);
       }

But I had overlooked that there is PhabricatorProjectColumnQuery in the call trace which is the root cause:
The projectPHID array condition in https://phabricator.wikimedia.org/source/phabricator/browse/wmf%252Fstable/src/applications/project/query/PhabricatorProjectColumnQuery.php;25aebab655fdb50118b8dccc6a23981b8b43580b$188-193 does:

if ($this->projectPHIDs !== null) // returns true; that is the current code and the culprit as that array is empty
if ($this->projectPHIDs)          // returns false as it should, just for testing and not current code
if (!empty($this->projectPHIDs))  // returns false as it should, just for testing and not current code

In my limited understanding of PHP, !== null is the same as isset() which returns true for an empty array (and thus blows up here)?

I also kind of wondered why Phab at this stage queries project columns but maybe it filters for projects only which have boards. Which would be neat. But also makes no sense if we have no projectPHID in the query?

Obviously I don't fully understand everything going on here but it's a start.

Aklapper moved this task from Backlog to Reported Upstream on the Upstream board.
Aklapper moved this task from Backlog to Upstreamed on the Phabricator (Upstream) board.

This issue should now be fixed on phabricator.wikimedia.org after today's software deployment in T404134.