phacility/phabricator · error · Exception

Parameter "%s" must contain a list of transaction descriptio

Error message

Parameter "%s" must contain a list of transaction descriptions, but item with key "%s" is not a dictionary.

What it means

Once the 'transactions' parameter is an array, getRawConduitTransactions() iterates it and requires every element to itself be an array (a dictionary describing one transaction). This exception is thrown when an item is a scalar, e.g. a string or integer.

Source

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

      ),
      '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(
            'Parameter "%s" must contain a list of transaction descriptions, '.
            'but item with key "%s" is missing a "type" field. Each '.
            'transaction must have a type field.',
            $transactions_key,
            $key));
      }

      if (!array_key_exists('value', $xaction)) {

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Give every element both a 'type' key and a 'value' key: [{"type":"...","value":...}]
  2. Validate the payload shape client-side before the call (every element is a dict)
  3. Map any shorthand strings to full dictionaries in a helper before sending

Example fix

// before
'transactions' => array('title', 'Fix login bug'),
// Exception: ... item with key "0" is not a dictionary.

// after
'transactions' => array(
  array('type' => 'title', 'value' => 'Fix login bug'),
),
Defensive patterns

Strategy: validation

Validate before calling

foreach ($parameters['transactions'] as $i => $txn) {
  if (!is_array($txn)) {
    throw new InvalidArgumentException(
      sprintf('transactions[%d] must be a dict with type+value', $i));
  }
}

Type guard

function isTransactionDict($txn) {
  return is_array($txn)
    && isset($txn['type'])
    && array_key_exists('value', $txn);
}

Try / catch

try {
  $result = $client->callMethod('maniphest.edit', $parameters);
} catch (ConduitClientException $ex) {
  if (strpos($ex->getMessage(), 'is not a dictionary') !== false) {
    // the offending index is named in the message; fix that element
  } else {
    throw $ex;
  }
}

Prevention

When it happens

Trigger: Sending transactions => ["title"] or transactions => ["title", "x"] instead of transactions => [{"type":"title","value":"x"}]; mixing a bare string into an otherwise correct list.

Common situations: Shorthand attempts to use compact type strings; merging user input or CLI argv entries directly into the transactions list; template engines producing flat arrays of strings.

Related errors


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