yiisoft/yii2 · error · yii\base\InvalidConfigException
Invalid link: it must be an array of key-value pairs.
Error message
Invalid link: it must be an array of key-value pairs.
What it means
populateRelation() requires the relation query's link property to be an array of key-value pairs mapping primary-model columns to related-model columns. hasMany()/hasOne() normally set it, but when a relation getter passes a non-array $link, or a hand-built ActiveQuery never sets ->link, InvalidConfigException is thrown the moment the relation is populated, eagerly (joinWith/with) or lazily.
Source
Thrown at framework/db/ActiveRelationTrait.php:229
$modelClass = $this->modelClass;
$inverseRelation = $modelClass::instance()->getRelation($this->inverseOf);
}
$result[$i][$this->inverseOf] = $inverseRelation->multiple ? [$this->primaryModel] : $this->primaryModel;
}
}
}
/**
* Finds the related records and populates them into the primary models.
* @param string $name the relation name
* @param array $primaryModels primary models
* @return array the related models
* @throws InvalidConfigException if [[link]] is invalid
*/
public function populateRelation($name, &$primaryModels)
{
if (!is_array($this->link)) {
throw new InvalidConfigException('Invalid link: it must be an array of key-value pairs.');
}
if ($this->via instanceof self) {
// via junction table
/** @var self<ActiveRecord|array<string, mixed>> $viaQuery */
$viaQuery = $this->via;
$viaModels = $viaQuery->findJunctionRows($primaryModels);
$this->filterByModels($viaModels);
} elseif (is_array($this->via)) {
// via relation
/** @var self<ActiveRecord|array<string, mixed>>|ActiveQueryTrait $viaQuery */
list($viaName, $viaQuery) = $this->via;
if ($viaQuery->asArray === null) {
// inherit asArray from primary query
$viaQuery->asArray($this->asArray);
}
$viaQuery->primaryModel = null;
$viaModels = array_filter($viaQuery->populateRelation($viaName, $primaryModels));View on GitHub (pinned to 66f00d18a2)
Solutions
- Pass the link as an array: $this->hasMany(Item::class, ['order_id' => 'id']) where the key is the related table's column and the value the primary table's column
- Audit every getXyz() relation getter in the involved model for a malformed link argument
- For manually constructed relation queries, set ->link explicitly to an array before returning them
Example fix
// before
public function getItems()
{
return $this->hasMany(Item::class, 'order_id'); // string link -> throws on populate
}
// after
public function getItems()
{
return $this->hasMany(Item::class, ['order_id' => 'id']);
} Defensive patterns
Strategy: validation
Validate before calling
// sanity-check a relation definition before heavy use
$relation = $model->getItems();
if (!is_array($relation->link) || $relation->link === []) {
throw new InvalidConfigException('Relation getItems() must define an array link.');
} Try / catch
try {
$items = $order->items;
} catch (yii\base\InvalidConfigException $e) {
if (strpos($e->getMessage(), 'Invalid link') === 0) {
throw new RuntimeException('Broken relation definition in ' . get_class($order) . '::getItems()', 0, $e);
}
throw $e;
} Prevention
- Always write links as arrays: hasMany(X::class, ['fk' => 'pk'])
- Add a unit test that calls every relation getter and asserts is_array($query->link)
- Code-review relation getters for missing array brackets
When it happens
Trigger: Defining return $this->hasMany(Item::class, 'order_id') (string link) instead of ['order_id' => 'id']; building an ActiveQuery manually for a relation and forgetting ->link = [...]; calling joinWith('malformedRelation') where the getter returns such a query.
Common situations: Habits carried from other AR libraries where a single string names the foreign key; incomplete copy-paste of relation examples; refactoring relation getters and dropping the array brackets.
Related errors
- Invalid path alias: $alias
- Unsupported configuration type: ' . gettype($type)
- Object configuration must be an array containing a "class" o
- The "id" configuration for the Application is required.
- The "basePath" configuration for the Application is required
AI-assisted analysis of yiisoft/yii2@66f00d18a2 (2026-08-17).
Data as JSON: /api/errors/f346e4282a153511.
Report an issue: GitHub.