phacility/phabricator · warning · Exception

The command "!%s" is not a supported mail command. Valid com

Error message

The command "!%s" is not a supported mail command. Valid commands for this object are: %s.

What it means

Email reply handlers parse '!command' lines at the top of mail replies and validate each against the commands the target object actually supports. An unrecognized command raises this exception, listing the valid commands (and their aliases) for that object type.

Source

Thrown at src/applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php:159

      } else {
        $valid_commands = array();
        foreach ($list as $valid_command) {
          $aliases = $valid_command->getCommandAliases();
          if ($aliases) {
            foreach ($aliases as $key => $alias) {
              $aliases[$key] = '!'.$alias;
            }
            $aliases = implode(', ', $aliases);
            $valid_commands[] = pht(
              '!%s (or %s)',
              $valid_command->getCommand(),
              $aliases);
          } else {
            $valid_commands[] = '!'.$valid_command->getCommand();
          }
        }

        throw new Exception(
          pht(
            'The command "!%s" is not a supported mail command. Valid '.
            'commands for this object are: %s.',
            $command,
            implode(', ', $valid_commands)));
      }
    }

    return $xactions;
  }

}

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Read the error text: it enumerates the valid '!commands' for that object type; resend the reply using one of them.
  2. Remove the offending '!command' line and perform the action from the web UI.
  3. Check the object's Mail Commands section in the application docs (or the handler class) for the supported list and aliases.
  4. If the workflow genuinely needs the command, implement a custom MetaMTAEmailTransactionCommand and register it with the handler.

Example fix

// before (email reply body)
!resolve now

// after (email reply body)
!close
Defensive patterns

Strategy: try-catch

Validate before calling

// Before processing a reply, check the command against what the object supports
$valid = array();
foreach ($object->getApplicationObjectEmailCommandObjects() as $command) {
  $valid[strtolower($command->getCommand())] = true;
}
if ($command !== null && empty($valid[strtolower($command)])) {
  // bounce a friendly reply listing valid commands instead of crashing the receiver
}

Try / catch

try {
  $xactions = $handler->processEmailCommand($command, $body);
} catch (Exception $ex) {
  if (strpos($ex->getMessage(), 'not a supported mail command') !== false) {
    // send the user an error email containing the valid command list
  }
}

Prevention

When it happens

Trigger: Replying to a Maniphest task email with a command the Maniphest reply handler does not define (e.g. '!resolve' when only '!close', '!claim', etc. exist), or using a Differential command like '!request' on an object whose handler implements a different set.

Common situations: Users guessing command names across applications ('!approve' on tasks, '!claim' on revisions where unsupported); command renamed between Phabricator versions; custom reply handlers with a narrower command list than users expect.

Related errors


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