phacility/phabricator · error · Exception

Parameter "%s" is not a list of transactions.

Error message

Parameter "%s" is not a list of transactions.

What it means

Edit-engine Conduit methods (maniphest.edit, differential.revision.edit, ...) pass the 'transactions' parameter to getRawConduitTransactions(), which first requires it to be a PHP array. This exception fires when the client sent anything that is not a list at all — a JSON string, a number, or null (parameter omitted).

Source

Thrown at src/applications/transactions/editengine/PhabricatorEditEngine.php:2190

        'phid' => $xaction->getPHID(),
      );
    }

    return array(
      'object' => array(
        'id' => (int)$object->getID(),
        'phid' => $object->getPHID(),
      ),
      'transactions' => $xactions_struct,
    );
  }

  private function getRawConduitTransactions(ConduitAPIRequest $request) {
    $transactions_key = 'transactions';

    $xactions = $request->getValue($transactions_key);
    if (!is_array($xactions)) {
      throw new Exception(
        pht(
          'Parameter "%s" is not a list of transactions.',
          $transactions_key));
    }

    foreach ($xactions as $key => $xaction) {
      if (!is_array($xaction)) {
        throw new Exception(
          pht(
            'Parameter "%s" must contain a list of transaction descriptions, '.
            'but item with key "%s" is not a dictionary.',
            $transactions_key,
            $key));
      }

      if (!array_key_exists('type', $xaction)) {
        throw new Exception(
          pht(

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Send 'transactions' as a real list of dictionaries, e.g. [{"type":"title","value":"New title"}]
  2. If building the request body with json_encode/json.dumps, apply it exactly once to the whole payload
  3. Omit nothing: every edit call needs transactions (even if only a 'comment' entry)
  4. Log the exact payload you send and confirm transactions parses to a list before dispatch

Example fix

// before: transactions double-encoded as a JSON string
$parameters = array(
  'objectIdentifier' => 123,
  'transactions' => json_encode(array(array('type' => 'title', 'value' => 'x'))),
);
$client->callMethod('maniphest.edit', $parameters);
// Exception: Parameter "transactions" is not a list of transactions.

// after: pass the raw list and let the client encode the whole body once
$parameters = array(
  'objectIdentifier' => 123,
  'transactions' => array(array('type' => 'title', 'value' => 'x')),
);
$client->callMethod('maniphest.edit', $parameters);
Defensive patterns

Strategy: validation

Validate before calling

// Structural pre-flight before any *.edit call:
function transactionsValid($txns) {
  if (!is_array($txns) || $txns === array()) {
    return false;
  }
  foreach ($txns as $txn) {
    if (!is_array($txn)) { return false; }
    if (!array_key_exists('type', $txn)) { return false; }
    if (!array_key_exists('value', $txn)) { return false; }
  }
  return true;
}
if (!transactionsValid($parameters['transactions'])) {
  // fix the payload locally; do not send it
}

Type guard

function isConduitTransactionList($value) {
  return is_array($value)
    && array_filter($value, 'is_array') === $value
    && $value === array_values($value);
}

Try / catch

try {
  $result = $client->callMethod('maniphest.edit', $parameters);
} catch (ConduitClientException $ex) {
  if (strpos($ex->getMessage(), 'is not a list of transactions') !== false) {
    // client bug: payload serialization; fix sender, do not retry as-is
  } else {
    throw $ex;
  }
}

Prevention

When it happens

Trigger: Calling an *.edit Conduit method with transactions serialized as a string (e.g. transactions => '[{"type":"title","value":"x"}]' instead of an actual list), sending an integer, or omitting the parameter entirely when the method requires it.

Common situations: Hand-built JSON bodies where json_encode was applied twice; client libraries that stringify complex params; Python callers passing a str instead of list; curl -d with manual JSON where transactions is quoted.

Related errors


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