phacility/phabricator · error · Exception

Unsupported action "%s".

Error message

Unsupported action "%s".

What it means

differential.createcomment validates its action parameter against a fixed map: 'accept', 'reject', 'resign', 'request_review' and 'rethink' map to modular revision transactions, while 'comment' and 'none' mean 'post the message only'. Any other non-empty action throws a plain Exception with the message 'Unsupported action "%s".', which Conduit reports as a generic call error carrying that text (there is no dedicated ERR_ code for it).

Source

Thrown at src/applications/differential/conduit/DifferentialCreateCommentConduitAPIMethod.php:80

      'reject' => DifferentialRevisionRejectTransaction::TRANSACTIONTYPE,
      'resign' => DifferentialRevisionResignTransaction::TRANSACTIONTYPE,
      'request_review' =>
        DifferentialRevisionRequestReviewTransaction::TRANSACTIONTYPE,
      'rethink' => DifferentialRevisionPlanChangesTransaction::TRANSACTIONTYPE,
    );

    $action = $request->getValue('action');
    if (isset($modular_map[$action])) {
      $xactions[] = id(new DifferentialTransaction())
        ->setTransactionType($modular_map[$action])
        ->setNewValue(true);
    } else if ($action) {
      switch ($action) {
        case 'comment':
        case 'none':
          break;
        default:
          throw new Exception(
            pht(
              'Unsupported action "%s".',
              $action));
          break;
      }
    }

    $content = $request->getValue('message');
    if (strlen($content)) {
      $xactions[] = id(new DifferentialTransaction())
        ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
        ->attachComment(
          id(new DifferentialTransactionComment())
            ->setContent($content));
    }

    // NOTE: The legacy "attach_inlines" flag is now ignored and has no
    // effect. See T13513.

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Use only the supported actions: accept, reject, resign, request_review, rethink, comment, none - or omit action entirely when only posting a message
  2. For abandon/close behavior use differential.closerevision or differential.revision.edit transactions instead
  3. Normalize the value before sending: lowercase, underscores instead of hyphens
  4. If you inherited an old script, audit every action literal it can emit

Example fix

// before
$params = array(
  'revision_id' => 456,
  'action' => 'plan_changes',
  'message' => 'Please rework this.',
);

// after
$params = array(
  'revision_id' => 456,
  'action' => 'rethink',
  'message' => 'Please rework this.',
);
Defensive patterns

Strategy: validation

Validate before calling

$allowed = array(
  'accept', 'reject', 'resign',
  'request_review', 'rethink', 'comment', 'none',
);
if ($action !== null && $action !== ''
    && !in_array(strtolower($action), $allowed, true)) {
  throw new InvalidArgumentException('Unsupported action: '.$action);
}

Try / catch

try {
  $client->callMethodSynchronous('differential.createcomment', $params);
} catch (ConduitClientException $ex) {
  if (strpos($ex->getMessage(), 'Unsupported action') !== false) {
    // fall back to a plain comment (drop the action)
    unset($params['action']);
    $client->callMethodSynchronous('differential.createcomment', $params);
  } else {
    throw $ex;
  }
}

Prevention

When it happens

Trigger: Sending action values such as 'abandon', 'claim', 'plan_changes', 'request-review', 'Accept', or any string not in {accept, reject, resign, request_review, rethink, comment, none} while also sending a non-empty message.

Common situations: Scripts written against pre-modular Phabricator where extra actions existed; copy-pasting action names from the web UI; hyphen-vs-underscore or case mismatches; client code defaulting the action to something like 'comment_or_none' when no action is intended.

Related errors


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