{"record":{"id":"6832062de8050461","repo":"phacility/phabricator","slug":"unexpected-hint-format-at-index-s-s","errorCode":null,"errorMessage":"Unexpected hint format at index \"%s\": %s","messagePattern":"Unexpected hint format at index \"(.+?)\": (.+?)","errorType":"console","errorClass":"PhutilArgumentUsageException","httpStatus":null,"severity":"error","filePath":"src/applications/repository/management/PhabricatorRepositoryManagementHintWorkflow.php","lineNumber":57,"sourceCode":"      if (!is_array($hint)) {\n        throw new PhutilArgumentUsageException(\n          pht(\n            'Each item in the list of hints should be a JSON object, but '.\n            'the item at index \"%s\" is not.',\n            $idx));\n      }\n\n      try {\n        PhutilTypeSpec::checkMap(\n          $hint,\n          array(\n            'repository' => 'string|int',\n            'old' => 'string',\n            'new' => 'optional string|null',\n            'hint' => 'string',\n          ));\n      } catch (Exception $ex) {\n        throw new PhutilArgumentUsageException(\n          pht(\n            'Unexpected hint format at index \"%s\": %s',\n            $idx,\n            $ex->getMessage()));\n      }\n\n      $repository_identifier = $hint['repository'];\n      $repository = idx($repositories, $repository_identifier);\n      if (!$repository) {\n        $repository = id(new PhabricatorRepositoryQuery())\n          ->setViewer($viewer)\n          ->withIdentifiers(array($repository_identifier))\n          ->executeOne();\n        if (!$repository) {\n          throw new PhutilArgumentUsageException(\n            pht(\n              'Repository identifier \"%s\" (in hint at index \"%s\") does not '.\n              'identify a valid repository.',","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/repository/management/PhabricatorRepositoryManagementHintWorkflow.php#L39-L75","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","solutions":["Match the schema exactly per entry: `{\"repository\": \"R1\"|123, \"old\": \"<sha>\", \"new\": \"<sha>\"|null, \"hint\": \"<text>\"}` (`new` optional).","Remove unknown/misspelled keys — checkMap fails on extra keys too.","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`.","Read the embedded TypeSpec message; it names the exact key and expected type."],"exampleFix":"// before\n[{\"repository\":\"R1\",\"old\":\"deadbeef\"}]  // missing required \"hint\"\n\n// after\n[{\"repository\":\"R1\",\"old\":\"deadbeef\",\"new\":null,\"hint\":\"commit rewritten during history migration\"}]","handlingStrategy":"validation","validationCode":"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","typeGuard":"function is_valid_hint($hint): bool {\n  if (!is_array($hint)) return false;\n  $known = array('repository','old','new','hint');\n  if ($unknown = array_diff(array_keys($hint), $known)) return false;\n  if (!isset($hint['repository']) || !is_string($hint['repository']) && !is_int($hint['repository'])) return false;\n  if (!isset($hint['old'], $hint['hint'])) return false;\n  if (!is_string($hint['old']) || !is_string($hint['hint'])) return false;\n  if (array_key_exists('new', $hint) && $hint['new'] !== null && !is_string($hint['new'])) return false;\n  return true;\n}","tryCatchPattern":null,"preventionTips":["Keep a canonical example hints file and copy it as a template.","Remember checkMap rejects unknown keys too — no extra metadata fields in hint objects.","Automate generation from `PhabricatorRepositoryCommitHint`-shaped data instead of editing JSON by hand."],"tags":["phabricator","phorge","json","schema","phutil-typespec","cli"],"backgroundTag":"schema-validation-failed","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}