phacility/phabricator · error · Exception
Constraint "%s" is not a valid constraint for this query.
Error message
Constraint "%s" is not a valid constraint for this query.
What it means
After validating that 'constraints' is a map, the engine collects every legal constraint key from the search engine's fields (getValidConstraintKeys()) and rejects any submitted key not in that set. This catches misspelled or unsupported constraint names before query construction, e.g. asking `maniphest.search` for a constraint only `differential.search` supports.
Source
Thrown at src/applications/search/engine/PhabricatorApplicationSearchEngine.php:1182
$fields = $this->getSearchFieldsForConduit();
foreach ($fields as $key => $field) {
if (!$field->getConduitParameterType()) {
unset($fields[$key]);
}
}
$valid_constraints = array();
foreach ($fields as $field) {
foreach ($field->getValidConstraintKeys() as $key) {
$valid_constraints[$key] = true;
}
}
foreach ($constraints as $key => $constraint) {
if (empty($valid_constraints[$key])) {
throw new Exception(
pht(
'Constraint "%s" is not a valid constraint for this query.',
$key));
}
}
foreach ($fields as $field) {
if (!$field->getValueExistsInConduitRequest($constraints)) {
continue;
}
$value = $field->readValueFromConduitRequest(
$constraints,
$request->getIsStrictlyTyped());
$saved_query->setParameter($field->getKey(), $value);
}
// NOTE: Currently, when running an ad-hoc query we never persist it intoView on GitHub (pinned to 5720a38cfe)
Solutions
- Open the method's Conduit documentation (UI: Applications > Conduit > <app>.search) and copy the exact constraint key list; the error names only the first bad key, so check all of them.
- Update scripts after Phabricator upgrades - constraint keys occasionally get renamed; keep them in one config spot, not inlined per script.
- Remove constraint keys the engine does not support rather than passing empty values as placeholders.
- For custom applications, ensure each custom SearchField exposes a Conduit parameter type so its keys become valid.
Example fix
// before
{"constraints": {"status": ["open"], "owner": ["alice"]}}
// after
{"constraints": {"statuses": ["open"], "ownerPHIDs": ["PHID-USER-xxxx"]}} Defensive patterns
Strategy: validation
Validate before calling
// Whitelist against the engine's own field list before sending
$valid = array();
foreach ($engine->getSearchFieldsForConduit() as $field) {
foreach ($field->getValidConstraintKeys() as $k) { $valid[$k] = true; }
}
$constraints = array_intersect_key($constraints, $valid); Type guard
function isValidConstraintKey($engine, $key) { $valid = array(); foreach ($engine->getSearchFieldsForConduit() as $f) { foreach ($f->getValidConstraintKeys() as $k) { $valid[$k] = true; } } return isset($valid[$key]); } Try / catch
try {
$response = conduct_conduit_call('maniphest.search', $params);
} catch (Exception $ex) {
if (strpos($ex->getMessage(), 'not a valid constraint') !== false) {
// strip the named key and retry with remaining constraints
unset($params['constraints'][$badKey]);
}
} Prevention
- Copy constraint keys from the Conduit method documentation page, not from memory
- Centralize constraint names in one constant map per app in your scripts
- Re-read docs after upgrading Phabricator - keys get renamed
When it happens
Trigger: Conduit `<app>.search` with `"constraints": {"status": ["open"]}` where the engine only knows 'statuses' (singular vs plural), or cross-application keys like using 'repositories' on user.search; also custom engines where a field lacks a Conduit parameter type and thus exposes no valid keys.
Common situations: Guessing constraint names from UI labels instead of the Conduit API documentation page (every method documents its exact constraint keys); version drift - constraint renamed across Phabricator releases while scripts kept the old name; singular/plural and camelCase/snake_case mistakes ('authorPHIDs' vs 'authors').
Related errors
- Minimum page size for API searches is 1, but this call speci
- Service "%s" is unrecognized, restricted, or you do not have
- Service type "%s" is unrecognized. Valid types are: %s.
- Transaction value when deleting Almanac properties must be a
- When deleting Almanac properties, each property name must be
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/19f7826c7b277742.
Report an issue: GitHub.