{"record":{"id":"c50c8bab996e11ec","repo":"phacility/phabricator","slug":"when-using-caches-you-must-select-at-least-on","errorCode":null,"errorMessage":"When using \"--caches\", you must select at least one valid cache to purge.","messagePattern":"When using \"--caches\", you must select at least one valid cache to purge\\.","errorType":"console","errorClass":"PhutilArgumentUsageException","httpStatus":null,"severity":"warning","filePath":"src/applications/cache/management/PhabricatorCacheManagementPurgeWorkflow.php","lineNumber":60,"sourceCode":"    if ($is_all) {\n      $purgers = $all_purgers;\n    } else {\n      $key_list = preg_split('/[\\s,]+/', $key_list);\n      $purgers = array();\n      foreach ($key_list as $key) {\n        if (isset($all_purgers[$key])) {\n          $purgers[$key] = $all_purgers[$key];\n        } else {\n          throw new PhutilArgumentUsageException(\n            pht(\n              'Cache purger \"%s\" is not recognized. Available caches '.\n              'are: %s.',\n              $key,\n              implode(', ', array_keys($all_purgers))));\n        }\n      }\n      if (!$purgers) {\n        throw new PhutilArgumentUsageException(\n          pht(\n            'When using \"--caches\", you must select at least one valid '.\n            'cache to purge.'));\n      }\n    }\n\n    $viewer = $this->getViewer();\n\n    foreach ($purgers as $key => $purger) {\n      $purger->setViewer($viewer);\n\n      echo tsprintf(\n        \"%s\\n\",\n        pht(\n          'Purging \"%s\" cache...',\n          $key));\n\n      $purger->purgeCache();","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/cache/management/PhabricatorCacheManagementPurgeWorkflow.php#L42-L78","documentation":"Thrown by bin/cache purge when, after splitting --caches and keeping recognized keys, the selected purger set is empty. In practice it is nearly unreachable from the CLI because any unrecognized or empty token triggers the per-key error (202) first; it exists as a defensive fallback, e.g. for code that constructs the workflow programmatically.","triggerScenarios":"Programmatically invoking the workflow with a caches value that resolves to zero purgers after filtering; modified/extended workflow code that pre-filters $key_list.","commonSituations":"Custom wrappers that sanitize the cache list before calling execute() and accidentally filter everything out; empty-string tokens in exotic inputs.","solutions":["Pass at least one valid cache key: 'bin/cache purge --caches general'.","In wrapper code, assert count($purgers) >= 1 after filtering and before proceeding.","Log the raw --caches value to spot over-aggressive sanitization that strips every token."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"$valid = array_keys(PhabricatorCachePurger::getAllPurgers());\n$wanted = preg_split('/[\\s,]+/', (string)$args->getArg('caches'), -1, PREG_SPLIT_NO_EMPTY);\n$selected = array_values(array_intersect($wanted, $valid));\nif (!$selected) {\n  fwrite(STDERR, \"No valid caches selected; nothing to do.\\n\");\n  exit(1);\n}\n$args->setArg('caches', implode(',', $selected));","typeGuard":null,"tryCatchPattern":"try {\n  $workflow->execute($args);\n} catch (PhutilArgumentUsageException $ex) {\n  fwrite(STDERR, $ex->getMessage().\"\\n\");\n  exit(1);\n}","preventionTips":["Filter the cache list against registered purgers before invoking execute().","Assert count($selected) >= 1 in wrappers after any sanitization step.","Log the raw input list when it sanitizes down to nothing."],"tags":["phabricator","cli","cache","empty-selection","defensive-guard"],"backgroundTag":"empty-selection","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}