{"record":{"id":"66e91e962472ba1b","repo":"phacility/phabricator","slug":"no-custom-field-key-specified","errorCode":null,"errorMessage":"No custom field key specified.","messagePattern":"No custom field key specified\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/infrastructure/customfield/datasource/PhabricatorStandardSelectCustomFieldDatasource.php","lineNumber":49,"sourceCode":"    if (!$reflection->implementsInterface($interface)) {\n      throw new Exception(\n        pht(\n          'Custom field class \"%s\" does not implement interface \"%s\".',\n          $class,\n          $interface));\n    }\n\n    $role = $this->getParameter('role');\n    if (!strlen($role)) {\n      throw new Exception(pht('No custom field role specified.'));\n    }\n\n    $object = newv($class, array());\n    $field_list = PhabricatorCustomField::getObjectFields($object, $role);\n\n    $field_key = $this->getParameter('key');\n    if (!strlen($field_key)) {\n      throw new Exception(pht('No custom field key specified.'));\n    }\n\n    $field = null;\n    foreach ($field_list->getFields() as $candidate_field) {\n      if ($candidate_field->getFieldKey() == $field_key) {\n        $field = $candidate_field;\n        break;\n      }\n    }\n\n    if ($field === null) {\n      throw new Exception(\n        pht(\n          'No field with field key \"%s\" exists for objects of class \"%s\" with '.\n          'custom field role \"%s\".',\n          $field_key,\n          $class,\n          $role));","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/infrastructure/customfield/datasource/PhabricatorStandardSelectCustomFieldDatasource.php#L31-L67","documentation":"The datasource requires a `key` parameter naming which custom field to offer typeahead options for. If `key` is missing or an empty string, loadResults throws immediately after building the field list.","triggerScenarios":"Wiring the datasource with `object` and `role` but never setting `key`, or passing an empty string because the field key variable was null/typo'd when the parameter array was built.","commonSituations":"Function-wiring code that derives the key from configuration and silently yields '' when the config entry is missing; copy-paste datasource setup that drops one parameter; key constants renamed between versions.","solutions":["Set `key` to the target field's getFieldKey() value (e.g. 'std:maniphest:priority' style keys for standard fields).","Find the exact key by listing the object's fields (field list -> getFields() -> getFieldKey()) or from the field's configuration in Config → Custom Fields.","Ensure the code path that computes the key cannot pass an empty string; default it explicitly."],"exampleFix":"// before\n$datasource->setParameter('key', '');\n// after\n$datasource->setParameter('key', 'std:maniphest:priority');","handlingStrategy":"validation","validationCode":"$key = $datasource->getParameter('key');\nif (!strlen((string)$key)) {\n  throw new Exception('datasource parameter \"key\" is required');\n}","typeGuard":"function hasCompleteSelectDatasourceParams($datasource) {\n  foreach (array('object', 'role', 'key') as $param) {\n    if (!strlen((string)$datasource->getParameter($param))) {\n      return false;\n    }\n  }\n  return true;\n}","tryCatchPattern":null,"preventionTips":["Never derive `key` from unvalidated user/config input without a non-empty check.","Discover keys programmatically from the field list rather than hardcoding, so renames surface as empty results, not wiring bugs."],"tags":["php","phabricator","custom-fields","typeahead","datasource"],"backgroundTag":"custom-field-datasource-misuse","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}