aureuserp/aureuserp · error · Exception

No source location defined on stock rule: :name!

Error message

No source location defined on stock rule: :name!

What it means

ProcurementRunner::runPullRules() iterates matched (request, rule) pairs for PULL actions and requires each rule to have a source_location_id — the generated moves source from that location. A pull rule without a source location throws immediately, naming the rule.

Source

Thrown at plugins/webkul/inventories/src/Services/ProcurementRunner.php:155

        return $freeStock;
    }

    protected function dispatch(RuleAction $action, Collection $pairs): void
    {
        match ($action) {
            RuleAction::PULL        => $this->runPullRules($pairs),
            RuleAction::BUY         => $this->runBuyRules($pairs),
            RuleAction::MANUFACTURE => $this->runManufactureRules($pairs),
            default                 => null,
        };
    }

    protected function runPullRules(Collection $pairs): void
    {
        foreach ($pairs as [$request, $rule]) {
            if (! $rule->source_location_id) {
                throw new \Exception(__('inventories::system.inventory-manager.run-procurement.no-source-location', [
                    'name' => $rule->name,
                ]));
            }
        }

        $byCompany = [];

        foreach ($pairs as [$request, $rule]) {
            $attributes = $this->buildMoveAttributes($rule, $request);

            $attributes['procure_method'] = $rule->procure_method === ProcureMethod::MTS_ELSE_MTO
                ? ProcureMethod::MAKE_TO_STOCK
                : $rule->procure_method;

            $byCompany[$request->company?->id][] = $attributes;
        }

        foreach ($byCompany as $attributeSets) {

View on GitHub (pinned to bd7cbeeb0c)

Solutions

  1. Open the named rule (Inventory > Configuration > Rules) and set its Source Location
  2. If the rule should not pull from anywhere, change its action away from Pull or disable it
  3. Add a validation step in rule-import tooling that rejects pull rules without a source location

Example fix

// before
// Rule 'WH: main -> stock' action=PULL, source_location_id = null
$runner->run($requests); // throws: no source location

// after
$rule->update(['source_location_id' => Location::where('type', LocationType::INTERNAL)->first()->id]);
$runner->run($requests);
Defensive patterns

Strategy: validation

Validate before calling

$badRules = Rule::where('action', RuleAction::PULL)
    ->whereNull('source_location_id')
    ->pluck('name');
if ($badRules->isNotEmpty()) {
    abort(422, 'Pull rules missing a source location: '.$badRules->implode(', '));
}
app(ProcurementRunner::class)->run($requests);

Type guard

function isRuleRunnable(\Webkul\Inventory\Models\Rule $rule): bool
{
    return $rule->action !== RuleAction::PULL || $rule->source_location_id !== null;
}

Try / catch

try {
    $runner->run($requests);
} catch (\Exception $e) {
    if (str_contains($e->getMessage(), 'no source location')) {
        // set source_location_id on the named rule, then retry the procurement
    }
}

Prevention

When it happens

Trigger: A procurement/reorder run (e.g. reordering rule firing or MTO confirmation) matches a pull rule whose source_location_id is null. The throw happens before any move is created, so nothing is half-written by this check.

Common situations: Rules created via seeders/APIs that omit the source location; the field cleared in the UI or by a mass update; copies of rules that lost their location during data migration.

Related errors


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