phacility/phabricator · error · Exception
Commit message field "%s" was expected to render a string or
Error message
Commit message field "%s" was expected to render a string or null value, but rendered a "%s" instead.
What it means
differential.getcommitmessage iterates the commit-message field list and calls renderFieldValue($wire_value) on each field. The API contract requires every field to render either a string or null; if any field implementation returns another type (int, array, bool, object), the method throws a plain Exception naming the field key and the offending gettype(). This is a server-side invariant violation, almost always introduced by a custom commit-message field.
Source
Thrown at src/applications/differential/conduit/DifferentialGetCommitMessageConduitAPIMethod.php:108
// from, so we hit the same validation logic for values which came over
// the wire and which we generated.
$field_value = $field->readFieldValueFromConduit($field_value);
$value_map[$field_key] = $field_value;
}
$key_title = DifferentialTitleCommitMessageField::FIELDKEY;
$commit_message = array();
foreach ($field_list as $field_key => $field) {
$label = $field->getFieldName();
$wire_value = $value_map[$field_key];
$value = $field->renderFieldValue($wire_value);
$is_template = ($is_create && $field->isTemplateField());
if (!is_string($value) && !is_null($value)) {
throw new Exception(
pht(
'Commit message field "%s" was expected to render a string or '.
'null value, but rendered a "%s" instead.',
$field->getFieldKey(),
gettype($value)));
}
$is_title = ($field_key == $key_title);
if ($value === null || !strlen($value)) {
if ($is_template) {
$commit_message[] = $label.': ';
}
} else {
if ($is_title) {
$commit_message[] = $value;
} else {
$value = str_replace(View on GitHub (pinned to 5720a38cfe)
Solutions
- Find the offending field: the exception text names the field key - match it against your custom field FIELDKEY constants
- Fix renderFieldValue to return a string or null; format non-string data (implode arrays, cast scalars) before returning
- Return null for 'nothing to render' instead of false or an empty array
- Temporarily disable the custom field to confirm the diagnosis, then re-enable after the fix
Example fix
// before (custom field)
public function renderFieldValue($value) {
return $value; // may be int or array -> crashes getcommitmessage
}
// after
public function renderFieldValue($value) {
if ($value === null) {
return null;
}
if (is_array($value)) {
return implode(', ', $value);
}
return (string)$value;
} Defensive patterns
Strategy: type-guard
Type guard
// Guard inside every custom commit-message field.
public function renderFieldValue($value) {
if ($value === null) {
return null;
}
if (!is_string($value)) {
if (is_array($value)) {
$value = implode(', ', $value);
} else {
$value = (string)$value;
}
}
return $value;
} Try / catch
// Server-side wrapper while diagnosing a misbehaving field:
$value = $field->renderFieldValue($wire_value);
if (!is_string($value) && !is_null($value)) {
phlog(pht('Field %s rendered %s; suppressing.',
$field->getFieldKey(), gettype($value)));
$value = null;
} Prevention
- Treat string|null as the renderFieldValue contract and enforce it in code review
- Unit-test custom fields by calling renderFieldValue with all wire shapes
- After Phabricator upgrades, re-test every custom commit-message field
When it happens
Trigger: Installing a custom Differential commit-message field (or an extension overriding renderFieldValue) that returns an integer, array, or boolean - for example returning a raw epoch timestamp or a list of reviewers instead of a formatted string. Every getcommitmessage call then fails for revisions using that field.
Common situations: Site administrators adding custom fields for release notes or reviewer lines; fields written for the object-rendering API where arrays are fine, reused for commit messages where they are not; upstream field regressions after an upgrade.
Related errors
- ERR_NOT_FOUND
- ERR_BAD_REVISION
- Unsupported action "%s".
- Field "changes" must be non-empty.
- ERR-BAD-REVISION
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/da48cd86ca238dd7.
Report an issue: GitHub.