{"record":{"id":"76ba4eaf5953fd88","repo":"aureuserp/aureuserp","slug":"no-source-location-defined-on-stock-rule-name","errorCode":null,"errorMessage":"No source location defined on stock rule: :name!","messagePattern":"No source location defined on stock rule: :name!","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"plugins/webkul/inventories/src/Services/ProcurementRunner.php","lineNumber":155,"sourceCode":"\n        return $freeStock;\n    }\n\n    protected function dispatch(RuleAction $action, Collection $pairs): void\n    {\n        match ($action) {\n            RuleAction::PULL        => $this->runPullRules($pairs),\n            RuleAction::BUY         => $this->runBuyRules($pairs),\n            RuleAction::MANUFACTURE => $this->runManufactureRules($pairs),\n            default                 => null,\n        };\n    }\n\n    protected function runPullRules(Collection $pairs): void\n    {\n        foreach ($pairs as [$request, $rule]) {\n            if (! $rule->source_location_id) {\n                throw new \\Exception(__('inventories::system.inventory-manager.run-procurement.no-source-location', [\n                    'name' => $rule->name,\n                ]));\n            }\n        }\n\n        $byCompany = [];\n\n        foreach ($pairs as [$request, $rule]) {\n            $attributes = $this->buildMoveAttributes($rule, $request);\n\n            $attributes['procure_method'] = $rule->procure_method === ProcureMethod::MTS_ELSE_MTO\n                ? ProcureMethod::MAKE_TO_STOCK\n                : $rule->procure_method;\n\n            $byCompany[$request->company?->id][] = $attributes;\n        }\n\n        foreach ($byCompany as $attributeSets) {","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/aureuserp/aureuserp/blob/bd7cbeeb0c620985dfd9b88c56be7f3ea86be6b4/plugins/webkul/inventories/src/Services/ProcurementRunner.php#L137-L173","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Open the named rule (Inventory > Configuration > Rules) and set its Source Location","If the rule should not pull from anywhere, change its action away from Pull or disable it","Add a validation step in rule-import tooling that rejects pull rules without a source location"],"exampleFix":"// before\n// Rule 'WH: main -> stock' action=PULL, source_location_id = null\n$runner->run($requests); // throws: no source location\n\n// after\n$rule->update(['source_location_id' => Location::where('type', LocationType::INTERNAL)->first()->id]);\n$runner->run($requests);","handlingStrategy":"validation","validationCode":"$badRules = Rule::where('action', RuleAction::PULL)\n    ->whereNull('source_location_id')\n    ->pluck('name');\nif ($badRules->isNotEmpty()) {\n    abort(422, 'Pull rules missing a source location: '.$badRules->implode(', '));\n}\napp(ProcurementRunner::class)->run($requests);","typeGuard":"function isRuleRunnable(\\Webkul\\Inventory\\Models\\Rule $rule): bool\n{\n    return $rule->action !== RuleAction::PULL || $rule->source_location_id !== null;\n}","tryCatchPattern":"try {\n    $runner->run($requests);\n} catch (\\Exception $e) {\n    if (str_contains($e->getMessage(), 'no source location')) {\n        // set source_location_id on the named rule, then retry the procurement\n    }\n}","preventionTips":["Make source_location_id required in rule forms when action is Pull","Validate seeded/imported rules: pull rules must carry a source location","Smoke-test rule configuration with a dry run before enabling reorder automation"],"tags":["inventory","procurement","rules","configuration","pull-rules"],"backgroundTag":"missing-rule-configuration","analyzedSha":"bd7cbeeb0c620985dfd9b88c56be7f3ea86be6b4","analyzedAt":"2026-08-21T06:41:00.338Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}