phacility/phabricator · error · Exception
Configured datasource class "%s" must be a valid subclass of
Error message
Configured datasource class "%s" must be a valid subclass of "%s".
What it means
PhabricatorStandardCustomFieldDatasource::getDatasource() builds the typeahead datasource for a 'datasource'-type custom field from the field's 'datasource.class' configuration. Before instantiating, it verifies with is_subclass_of() that the configured class descends from PhabricatorTypeaheadDatasource; a missing, misspelled, unloaded or unrelated class name throws immediately. The error surfaces as soon as the field is rendered or its value edited (any tokenizer/datasource UI), and the two placeholders carry the configured class and the required parent.
Source
Thrown at src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDatasource.php:16
<?php
final class PhabricatorStandardCustomFieldDatasource
extends PhabricatorStandardCustomFieldTokenizer {
public function getFieldType() {
return 'datasource';
}
public function getDatasource() {
$parameters = $this->getFieldConfigValue('datasource.parameters', array());
$class = $this->getFieldConfigValue('datasource.class');
$parent = 'PhabricatorTypeaheadDatasource';
if (!is_subclass_of($class, $parent)) {
throw new Exception(
pht(
'Configured datasource class "%s" must be a valid subclass of '.
'"%s".',
$class,
$parent));
}
return newv($class, array())
->setParameters($parameters);
}
}
View on GitHub (pinned to 5720a38cfe)
Solutions
- Open the custom field's configuration and check the 'datasource.class' value; confirm it names an existing class.
- Verify that class actually extends PhabricatorTypeaheadDatasource (grep its definition).
- If the class is in an extension library, make sure the library is registered and its map rebuilt (arc liberate), then clear caches.
- Fix the class name and re-save the configuration.
Example fix
// before 'datasource.class' => 'MyProjectTaskSearchEngine', // after 'datasource.class' => 'MyProjectTaskDatasource', // MyProjectTaskDatasource extends PhabricatorTypeaheadDatasource
Defensive patterns
Strategy: validation
Validate before calling
$class = idx($field_spec, 'datasource.class');
if (!is_string($class) || !class_exists($class) || !is_subclass_of($class, 'PhabricatorTypeaheadDatasource')) {
// reject the field specification before it reaches the UI
} Type guard
function is_valid_datasource_class($class) {
return is_string($class)
&& class_exists($class)
&& is_subclass_of($class, 'PhabricatorTypeaheadDatasource');
} Prevention
- Grep the datasource class and confirm its declaration ends in 'extends PhabricatorTypeaheadDatasource' before referencing it.
- Add a config lint step that validates every 'datasource'-type custom field.
- Re-validate custom field config after every Phabricator or extension library upgrade.
When it happens
Trigger: Defining a standard custom field with getFieldType() 'datasource' whose field config sets 'datasource.class' to something that is not a PhabricatorTypeaheadDatasource subclass — e.g. a search engine class, a plain helper class, or a typo. Also triggered when the named class lives in an extension library that is not loaded, so is_subclass_of() returns false.
Common situations: Copy-pasting field config between installs where class names differ; referencing an application datasource class that was renamed during a Phabricator upgrade; forgetting to register the extension library so the class never loads.
Related errors
- Custom field class "%s" does not exist.
- Custom field class "%s" does not implement interface "%s".
- No custom field role specified.
- No custom field key specified.
- No field with field key "%s" exists for objects of class "%s
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/b99bcbd226ec5a65.
Report an issue: GitHub.