phacility/phabricator · error · Exception
No custom field role specified.
Error message
No custom field role specified.
What it means
The datasource requires a `role` parameter (e.g. PhabricatorCustomField::ROLE_EDIT, ROLE_VIEW, ROLE_DEFAULT) that selects which field list to build via PhabricatorCustomField::getObjectFields(). If the parameter is absent or an empty string, loadResults throws before doing any work.
Source
Thrown at src/infrastructure/customfield/datasource/PhabricatorStandardSelectCustomFieldDatasource.php:41
throw new Exception(
pht(
'Custom field class "%s" does not exist.',
$class));
}
$reflection = new ReflectionClass($class);
$interface = 'PhabricatorCustomFieldInterface';
if (!$reflection->implementsInterface($interface)) {
throw new Exception(
pht(
'Custom field class "%s" does not implement interface "%s".',
$class,
$interface));
}
$role = $this->getParameter('role');
if (!strlen($role)) {
throw new Exception(pht('No custom field role specified.'));
}
$object = newv($class, array());
$field_list = PhabricatorCustomField::getObjectFields($object, $role);
$field_key = $this->getParameter('key');
if (!strlen($field_key)) {
throw new Exception(pht('No custom field key specified.'));
}
$field = null;
foreach ($field_list->getFields() as $candidate_field) {
if ($candidate_field->getFieldKey() == $field_key) {
$field = $candidate_field;
break;
}
}
View on GitHub (pinned to 5720a38cfe)
Solutions
- Set the role parameter, e.g. `setParameter('role', PhabricatorCustomField::ROLE_EDIT)` (or the string 'edit').
- Choose the role matching how the field will be used: ROLE_EDIT for edit forms, ROLE_VIEW for rendering, ROLE_DEFAULT for general use.
- Audit the parameter array so `object`, `role`, and `key` are always all present.
Example fix
// before
$datasource->setParameter('object', 'ManiphestTask');
$datasource->setParameter('key', 'std:project:foo');
// after
$datasource->setParameter('object', 'ManiphestTask');
$datasource->setParameter('role', PhabricatorCustomField::ROLE_EDIT);
$datasource->setParameter('key', 'std:project:foo'); Defensive patterns
Strategy: validation
Validate before calling
foreach (array('object', 'role', 'key') as $param) {
if (!strlen((string)$datasource->getParameter($param))) {
throw new Exception('datasource parameter "'.$param.'" is required');
}
} Type guard
function hasCompleteSelectDatasourceParams($datasource) {
foreach (array('object', 'role', 'key') as $param) {
if (!strlen((string)$datasource->getParameter($param))) {
return false;
}
}
return true;
} Prevention
- Use the valid-role constants (PhabricatorCustomField::ROLE_EDIT / ROLE_VIEW / ROLE_DEFAULT) rather than ad-hoc strings.
- Set all three parameters in one helper call so a partial wiring cannot reach loadResults().
- Add a unit test that instantiates the datasource and calls loadResults() for each configured typeahead function.
When it happens
Trigger: Wiring the datasource with only `object` and `key` parameters and never setting `role`, or setting it to an empty string / null via setParameter('role', '').
Common situations: Copying datasource wiring from an example that omitted the role; conditionally setting parameters and skipping `role` on one path; building the parameter list dynamically and the role key gets dropped.
Related errors
- Custom field class "%s" does not exist.
- Custom field class "%s" does not implement interface "%s".
- No custom field key specified.
- No field with field key "%s" exists for objects of class "%s
- Field "%s" is not a standard select field, nor a proxy of a
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/2e9080626b8ed76d.
Report an issue: GitHub.