phacility/phabricator · warning · PhutilArgumentUsageException

This source ("%s") does not have any import cursors.

Error message

This source ("%s") does not have any import cursors.

What it means

Second guard in the Nuance import workflow: the source's definition does expose cursors (hasImportCursors() true), but getImportCursors() returned an empty list, so there is nothing to import right now. Thrown as a PhutilArgumentUsageException with the source name; distinct from 933 in that the mechanism exists but yields zero cursor objects.

Source

Thrown at src/applications/nuance/management/NuanceManagementImportWorkflow.php:42

  }

  public function execute(PhutilArgumentParser $args) {
    $source = $this->loadSource($args, 'source');

    $definition = $source->getDefinition()
      ->setViewer($this->getViewer())
      ->setSource($source);

    if (!$definition->hasImportCursors()) {
      throw new PhutilArgumentUsageException(
        pht(
          'This source ("%s") does not expose import cursors.',
          $source->getName()));
    }

    $cursors = $definition->getImportCursors();
    if (!$cursors) {
      throw new PhutilArgumentUsageException(
        pht(
          'This source ("%s") does not have any import cursors.',
          $source->getName()));
    }

    $select = $args->getArg('cursor');
    if (strlen($select)) {
      if (empty($cursors[$select])) {
        throw new PhutilArgumentUsageException(
          pht(
            'This source ("%s") does not have a "%s" cursor. Available '.
            'cursors: %s.',
            $source->getName(),
            $select,
            implode(', ', array_keys($cursors))));
      } else {
        echo tsprintf(
          "%s\n",

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Inspect the definition's getImportCursors() to learn why the list is empty — usually a missing integration config or a guard condition.
  2. Complete the prerequisite setup (API keys, linked account, enabled integration) so the definition produces its cursor(s), then rerun.
  3. If empty is legitimate for this type, skip invoking the import workflow for it in scripts.
  4. Check you targeted the right source — an adjacent source of the same type may have the cursor configured.

Example fix

// before: cursor list gated on configuration that is absent
public function getImportCursors() {
  $cursors = array();
  if ($this->getConfig('apikey')) { $cursors[] = new MyCursor(); }
  return $cursors;  // no apikey set -> [] -> err: "does not have any import cursors"
}

// after: configure the source
// bin/config edit source 12 -> set 'apikey', then rerun import
Defensive patterns

Strategy: validation

Validate before calling

$cursors = $definition->getImportCursors();
if (!$cursors) {
  // definition yields zero cursors: finish its prerequisite configuration
  // (API keys, linked accounts, enabled integrations) before importing
}

Prevention

When it happens

Trigger: Running 'bin/nuance import --source <name>' where the definition's getImportCursors() constructs and returns [] — for example a cursor factory that filters by configuration (enabled integrations) and everything is disabled, or a definition whose cursor list is built from a config key that is empty/unset.

Common situations: A new source type whose cursors are configuration-gated and the relevant integration is not configured; refactoring that moved cursor construction behind a check; a definition that returns cursors only when an external system is linked, before linking.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/2d398dcdfc7f8d2c. Report an issue: GitHub.