phacility/phabricator · error · Exception
No such variable '%s'!
Error message
No such variable '%s'!
What it means
HarbormasterBuildStepImplementation::mergeVariables() scans a pattern for ${name} placeholders and requires every name to be present in the variables dict before substituting values (it replaces placeholders with %s and calls $function, e.g. vsprintf). An unknown placeholder throws so the sprintf-style call can never receive a mismatched argument list or silently produce broken output.
Source
Thrown at src/applications/harbormaster/step/HarbormasterBuildStepImplementation.php:204
* ...into a string with variables merged into it safely:
*
* ls 'dir with spaces'
*
* @param string Name of a `vxsprintf` function, like @{function:vcsprintf}.
* @param string User-provided pattern string containing `${variables}`.
* @param dict List of available replacement variables.
* @return string String with variables replaced safely into it.
*/
protected function mergeVariables($function, $pattern, array $variables) {
$regexp = '@\\$\\{(?P<name>[a-z\\./_-]+)\\}@';
$matches = null;
preg_match_all($regexp, $pattern, $matches);
$argv = array();
foreach ($matches['name'] as $name) {
if (!array_key_exists($name, $variables)) {
throw new Exception(pht("No such variable '%s'!", $name));
}
$argv[] = $variables[$name];
}
$pattern = str_replace('%', '%%', $pattern);
$pattern = preg_replace($regexp, '%s', $pattern);
return call_user_func($function, $pattern, $argv);
}
public function getFieldSpecifications() {
return array();
}
protected function formatSettingForDescription($key, $default = null) {
return $this->formatValueForDescription($this->getSetting($key, $default));
}
View on GitHub (pinned to 5720a38cfe)
Solutions
- Correct the pattern so it only references variables that exist in the variables array (e.g. ${revision} not ${buildable.revision})
- Extend the variables array passed to mergeVariables to include the missing key
- Before editing templates, list the variables the implementation actually provides (shown in the plan editor help) and keep edits consistent with them
Example fix
// before
$pattern = 'make ${buildable.revision}'; // 'buildable.revision' not in $variables
$this->mergeVariables('vsprintf', $pattern, $variables);
// after
$pattern = 'make ${revision}';
$this->mergeVariables('vsprintf', $pattern, $variables); Defensive patterns
Strategy: validation
Validate before calling
preg_match_all('/[$][{]([a-z./_-]+)[}]/', $pattern, $m);
foreach ($m[1] as $name) {
if (!array_key_exists($name, $variables)) {
// fix the pattern or add the variable before calling mergeVariables
}
} Prevention
- Keep step templates and the variables map in the same change when editing plans
- Test edited plans with a dry-run build before relying on them
When it happens
Trigger: A command or field pattern containing ${buildable.revision} while the variables array passed to mergeVariables only provides other keys; renaming a variable key while old step configurations still reference the old name.
Common situations: Editing a build plan template to reference a variable the current build context does not provide; Phabricator upgrades that change available variable names; copying a step configuration between plans with different variable sets.
Related errors
- No implementation is specified!
- No such implementation "%s" exists!
- This object does not support builds with Buildkite.
- Object ("%s") does not implement interface "%s". Only object
- Invalid or unknown object ("%s") for land operation, expecte
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/70f469f4765d3438.
Report an issue: GitHub.