phacility/phabricator · error · PhutilArgumentUsageException

Unexpected hint format at index "%s": %s

Error message

Unexpected hint format at index "%s": %s

What it means

Thrown by `bin/repository hint` when `PhutilTypeSpec::checkMap()` rejects a hint object because its keys or value types do not match the required schema: `repository` (string|int), `old` (string), `hint` (string), and optional `new` (string|null). The workflow embeds the TypeSpec's own message naming the offending key. This validates each element after the list-shape check at index level.

Source

Thrown at src/applications/repository/management/PhabricatorRepositoryManagementHintWorkflow.php:57

      if (!is_array($hint)) {
        throw new PhutilArgumentUsageException(
          pht(
            'Each item in the list of hints should be a JSON object, but '.
            'the item at index "%s" is not.',
            $idx));
      }

      try {
        PhutilTypeSpec::checkMap(
          $hint,
          array(
            'repository' => 'string|int',
            'old' => 'string',
            'new' => 'optional string|null',
            'hint' => 'string',
          ));
      } catch (Exception $ex) {
        throw new PhutilArgumentUsageException(
          pht(
            'Unexpected hint format at index "%s": %s',
            $idx,
            $ex->getMessage()));
      }

      $repository_identifier = $hint['repository'];
      $repository = idx($repositories, $repository_identifier);
      if (!$repository) {
        $repository = id(new PhabricatorRepositoryQuery())
          ->setViewer($viewer)
          ->withIdentifiers(array($repository_identifier))
          ->executeOne();
        if (!$repository) {
          throw new PhutilArgumentUsageException(
            pht(
              'Repository identifier "%s" (in hint at index "%s") does not '.
              'identify a valid repository.',

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Match the schema exactly per entry: `{"repository": "R1"|123, "old": "<sha>", "new": "<sha>"|null, "hint": "<text>"}` (`new` optional).
  2. Remove unknown/misspelled keys — checkMap fails on extra keys too.
  3. Validate the whole file offline with jq: `jq '.[] | has("repository") and has("old") and has("hint") and (.repository|type=="string" or type=="number")' hints.json`.
  4. Read the embedded TypeSpec message; it names the exact key and expected type.

Example fix

// before
[{"repository":"R1","old":"deadbeef"}]  // missing required "hint"

// after
[{"repository":"R1","old":"deadbeef","new":null,"hint":"commit rewritten during history migration"}]
Defensive patterns

Strategy: validation

Validate before calling

jq -e 'all(.[]; (has("repository") and ((.repository|type)=="string" or (.repository|type)=="number")) and (.old|type)=="string" and (.hint|type)=="string" and ((has("new")|not) or .new==null or (.new|type)=="string"))' hints.json >/dev/null && ./bin/repository hint < hints.json

Type guard

function is_valid_hint($hint): bool {
  if (!is_array($hint)) return false;
  $known = array('repository','old','new','hint');
  if ($unknown = array_diff(array_keys($hint), $known)) return false;
  if (!isset($hint['repository']) || !is_string($hint['repository']) && !is_int($hint['repository'])) return false;
  if (!isset($hint['old'], $hint['hint'])) return false;
  if (!is_string($hint['old']) || !is_string($hint['hint'])) return false;
  if (array_key_exists('new', $hint) && $hint['new'] !== null && !is_string($hint['new'])) return false;
  return true;
}

Prevention

When it happens

Trigger: Omitting a required key (e.g. no `hint` or no `old`); passing `old` as an array or int; passing `new` as an int or bool instead of string/null; including misspelled keys (`repos` instead of `repository`) since checkMap rejects unknown keys; passing null for `repository`.

Common situations: Hand-authored hint files drop the `new` vs `old` distinction and only include the new SHA; renaming scripts emit `repo` instead of `repository`; `new` left as empty array `[]` from a default value in generator code.

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/6832062de8050461. Report an issue: GitHub.