phacility/phabricator · error · Exception

When deleting Almanac properties, each property name must…

Error message

When deleting Almanac properties, each property name must be a string. The value at index "%s" is not a string.

What it means

Thrown by AlmanacDeletePropertyEditType::generateTransactions() while iterating a 'property.delete' value list: each element must be a string property name, and the element at the reported index is not. This catches lists that contain integers, nested arrays, booleans, or nulls before a transaction is generated with an invalid metadata key ('almanac.property').

Solutions

  1. Inspect the element at the index named in the message and cast or rebuild the list so every entry is a property-name string.
  2. Validate the payload client-side: every item must be a string before submitting the transaction.
  3. If you meant to delete properties keyed by ID, map IDs to their property name strings first.

Example fix

// before
$value = array(0 => 'almanac.props.a', 1 => 42);

// after
$value = array('almanac.props.a', 'almanac.props.b');
Defensive patterns

Strategy: validation

Validate before calling

$names = [];
foreach ((array)$raw as $k => $v) {
  if (!is_string($v)) {
    continue; // or cast/log
  }
  $names[] = $v;
}
// send $names as property.delete value; every entry is a string

Type guard

function all_strings(array $list): bool {
  foreach ($list as $item) {
    if (!is_string($item)) return false;
  }
  return true;
}

Prevention

When it happens

Trigger: Sending {"type":"property.delete","value":[0,1]} (list of numeric indices); a JSON list containing null or a nested object; a PHP caller building the list with array_keys on a non-string-keyed array; a client that encodes a single-element tuple as ["name", null].

Common situations: Porting code from an API that accepted index/value pairs; debugging code that accidentally pushes the loop counter into the value list; language serializers that turn mixed arrays into JSON arrays with null placeholders.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at src/applications/almanac/engineextension/AlmanacDeletePropertyEditType.php:21

final class AlmanacDeletePropertyEditType
  extends PhabricatorEditType {

  public function generateTransactions(
    PhabricatorApplicationTransaction $template,
    array $spec) {

    $value = idx($spec, 'value');
    if (!is_array($value)) {
      throw new Exception(
        pht(
          'Transaction value when deleting Almanac properties must be a list '.
          'of property names.'));
    }

    $xactions = array();
    foreach ($value as $idx => $property_key) {
      if (!is_string($property_key)) {
        throw new Exception(
          pht(
            'When deleting Almanac properties, each property name must '.
            'be a string. The value at index "%s" is not a string.',
            $idx));
      }

      $xactions[] = $this->newTransaction($template)
        ->setMetadataValue('almanac.property', $property_key)
        ->setNewValue(true);
    }

    return $xactions;
  }

}

View on GitHub (pinned to 5720a38cfe)