aureuserp/aureuserp · error · Exception

Invalid rule's configuration, the following rule causes an e

Error message

Invalid rule's configuration, the following rule causes an endless loop: :name

What it means

Product::resolveRuleChain() walks pull/push rules starting from a location. Each hop finds the next rule via InventoryFacade::findRule(); if the chain reaches a rule that was already visited (same id), the configuration is a cycle and it throws with the offending rule's name instead of looping forever.

Source

Thrown at plugins/webkul/inventories/src/Models/Product.php:182

    }

    public function resolveRuleChain($location, $routes = null, ?Collection $seen = null): Collection
    {
        $seen ??= collect();

        $warehouse = $location->warehouse ?? ($seen->isNotEmpty() ? $seen->last()?->propagateWarehouse : null);

        $rule = InventoryFacade::findRule($this, $location, [
            'routes'    => $routes ?: collect(),
            'warehouse' => $warehouse,
        ]);

        if (! $rule) {
            return $seen;
        }

        if ($seen->contains(fn ($seenRule) => $seenRule->id === $rule->id)) {
            throw new \Exception(__('inventories::system.product.endless-loop-rule', ['name' => $rule->name]));
        }

        $seen->push($rule);

        if (
            $rule->procure_method === ProcureMethod::MAKE_TO_STOCK
            || ! in_array($rule->action, [RuleAction::PULL_PUSH, RuleAction::PULL], true)
        ) {
            return $seen;
        }

        return $this->resolveRuleChain($rule->sourceLocation, null, $seen);
    }

    public function procurementDates($date, $location, $routes = null): array
    {
        $rules = $this->resolveRuleChain($location, $routes);

View on GitHub (pinned to bd7cbeeb0c)

Solutions

  1. Open the named rule and break the cycle: change its source location so the chain no longer returns to a visited location
  2. Set the looping rule's procure method to MTS (MAKE_TO_STOCK) — the walk stops at MTS rules
  3. Delete or disable one of the mutually-referencing rules

Example fix

// before (cycle)
// Rule A: WH/Stock -> WH/Shelf 1, action pull_push, procure mts_else_mto
// Rule B: WH/Shelf 1 -> WH/Stock, action pull_push
$product->resolveRuleChain($location); // throws endless loop

// after
// Rule B: source changed to Vendors, procure mts -> chain terminates
$product->resolveRuleChain($location);
Defensive patterns

Strategy: validation

Validate before calling

// walk rules yourself with a visited set before running procurement
$seen = collect();
$loc = $startLocation;
while (true) {
    $rule = InventoryFacade::findRule($product, $loc, ['warehouse' => $loc->warehouse]);
    if (! $rule || $rule->procure_method === ProcureMethod::MAKE_TO_STOCK) {
        break;
    }
    if ($seen->contains(fn ($r) => $r->id === $rule->id)) {
        throw new \RuntimeException("Rule cycle detected at {$rule->name}");
    }
    $seen->push($rule);
    $loc = $rule->sourceLocation;
}

Try / catch

try {
    $chain = $product->resolveRuleChain($location);
} catch (\Exception $e) {
    // message names the looping rule: fix route configuration, do not retry unchanged
    report($e);
}

Prevention

When it happens

Trigger: Two or more PULL_PUSH/PULL rules whose source/destination locations feed each other (rule A pulls X->Y, rule B pulls Y->X), reachable from the product's location or warehouse; the throw happens when resolving procure method chains (MTS-else-MTO) during confirmation or procurement runs.

Common situations: Copy-pasted rules across global and warehouse routes with overlapping locations; a rule's source location set to another rule's destination; route changes or upgrades re-linking rules into a loop.

Related errors


AI-assisted analysis of aureuserp/aureuserp@bd7cbeeb0c (2026-08-21). Data as JSON: /api/errors/8cec6033887016ac. Report an issue: GitHub.