Logo run_as_root - Magento B2B Agentur Würzburg

Adobe Commerce CLI-Befehle: Probleme aus dem Nichts erschaffen

Technical
Adobe Commerce CLI-Befehle: Probleme aus dem Nichts erschaffen

Inhalte

Hallo zusammen,

In diesem Artikel zeige ich euch anhand praktischer Beispiele, wie unerwartete Probleme in Magento 2 & Adobe Commerce-Projekten entstehen können — beim Erstellen und Verwenden eigener CLI-Befehle oder solcher von Drittanbietern. Das wird besonders dann relevant, wenn ihr mit CI/CD-Pipelines arbeitet und dort Projekt-Setups sowie Tests ausführt.

Der Hauptdarsteller unseres Artikels: ISSUE: magento setup command is throwing magento.flag does't exist. Wir schauen uns dieses Problem genauer an, verstehen seine Ursachen und finden Wege, es zu beheben.

😁

Hinweis: Kurze Anmerkung zur Benennung — dieser Artikel behandelt sowohl Adobe Commerce als auch Magento 2. Denn Adobe Commerce ist Magento. Long Live Magento!

Das eigentliche Problem & seine Ursachen

Bei der Arbeit an verschiedenen Magento 2-Projekten bin ich immer wieder auf Probleme gestoßen, wenn ich ein `clean` Setup mit einer frisch erstellten Datenbank durchgeführt habe. Das passiert meist beim Aufsetzen von Integrations- oder Funktionstests in Pipelines & lokalen Umgebungen — aber auch bei Upgrades, Migrationen oder Deployments kann dieses Problem auftauchen.

Die Übeltäter? Hier sind zwei lästige Fehlermeldungen, die dir vielleicht bekannt vorkommen:

The default website isn't defined. Set the website and try again.

Bei Commerce-Editionen kommt außerdem noch diese hinzu:

SQLSTATE[42S02]: Base table or view not found: 1146 Table
'magento2.flag' doesn't exist, query was:
SELECT flag.* FROM flag WHERE (flag.flag_code='staging')

Wenn du diese Fehler während der Ausführung von `php bin/magento setup:install` siehst, geben sie wenig Aufschluss über das eigentliche Problem. Nach einigen frustrierenden Recherche-Stunden wirst du herausfinden, dass diese Fehler durch den vorzeitigen Zugriff auf die DB-Ressource entstehen — was die Initialisierung von Konfigurations- und Status-Entitäten aus der Magento-DB auslöst.

Das Dilemma: Du kannst zum jetzigen Zeitpunkt keine Daten aus der DB abrufen, weil die Tabellen noch gar nicht existieren. Sie werden erst während des Installationsprozesses erstellt und befüllt — nicht vorher. ¯\_(ツ)_/¯

Das klassische "Henne-Ei"-Dilemma

Wir stecken also in einem zirkulären Problem: Wir wollen das System installieren, werden aber daran gehindert, weil es noch nicht installiert ist. Verwirrend, oder?🤪

Das passiert, weil irgendwo jemand verfrüht auf die DB-Verbindung zugreift. Klingt offensichtlich — und ich hoffe, du bist so dankbar für diese Erkenntnis wie Sam Eliot.

Danke Captain Obvious

Dieser "Jemand" steckt in `bin/magento` und wird aufgerufen, bevor der eigentliche Befehl ausgeführt wird. Meistens sind die Konstruktoren der CLI-Befehle schuld. Ich erkläre dir warum.

Die Falle der CLI-Command-Konstruktoren

Schau dir zur Verdeutlichung diesen Code an:

class DoSmthing
{
    private ?string $dummyConfigValue;

    public function __construct(ScopeConfigInterface $storeManager)
    {
        $this->dummyConfigValue = $storeManager->getValue('some/dummy/path', ScopeInterface::SCOPE_STORE);
    }

    public function getValue(): ?string
    {
        return $this->dummyConfigValue;
    }
}

class DummyCommand extends Command
{
    // ...
    public function __construct(DoSmthing $model, string $name = null)
    {
        $this->model = $model;
        parent::__construct($name);
    }
    // ...
}

Die Wurzel des Problems liegt in den Konstruktoren beider Klassen.

In der Klasse DoSmthing wird versucht, einen Konfigurationswert abzurufen. Dieser Aufruf greift auf die Tabellen store, store_website und core_config_data zu — und zwar bereits beim Erstellen des DummyCommand-Objekts.

Und was passiert, wenn dieser Code läuft, bevor die Tabellen bereit sind? Genau — Fehler!

Noch einmal der Reihe nach

  1. Wir führen bin/magento setup:install aus.
  2. Die bin/magento-Anwendung erstellt alle Instanzen der CLI-Befehle.
  3. DummyCommand hängt von der Klasse DoSmthing ab — also muss DoSmthing erstellt werden, bevor das DummyCommand-Objekt erzeugt werden kann.
  4. Die Anwendung erstellt das DoSmthing-Objekt und führt die DoSmthing::__construct-Methode aus.
  5. Die DoSmthing::__construct-Methode ruft den Config Manager auf.
  6. Der Config Manager fragt Tabellen ab, die noch nicht erstellt wurden.
  7. FEHLER.

Strategien zur Vermeidung dieser Fehler

Merke dir diese goldene Regel: Jede CLI-Command-Klasse wird initialisiert, sobald du php bin/magento aufrufst. So sparst du dir künftige Kopfschmerzen:

  • Sei klug Es ist keine gute Idee, ressourcenintensive Operationen wie DB- oder API-Aufrufe in den __construct-Methoden von CLI-Command-Klassen zu platzieren. Diese Operationen werden selbst dann ausgeführt, wenn du nur die Liste der verfügbaren Befehle abrufst.
  • Sei vorbereitet Vermeide es, im __construct auf Ressourcen zu verweisen, die zur Laufzeit möglicherweise nicht verfügbar sind — vor allem, da Magento-Tabellen während setup:install noch nicht erstellt wurden.
  • Behebe das Problem Wenn du den problematischen Code nicht ändern kannst, injiziere einen Proxy über DI-Konfigurationen.

Das Problem aus unserem Beispiel mit DummyCommand lässt sich lösen, indem du folgende Zeilen zur di.xml hinzufügst:

<type name="AbcTest\DummyConsoleCommand\Console\Command\DummyCommand">
    <arguments>
        <argument name="model" xsi:type="object">
            \AbcTest\DummyConsoleCommand\Model\DoSmthing\Proxy
        </argument>
    </arguments>
</type>

Proxy ist ein bekanntes Pattern und wird in Magento häufig eingesetzt, um unnötige Code-Ausführungen zu vermeiden, bis wir die Ressource wirklich benötigen. In unserem Beispiel wird das DoSmthing-Objekt erst dann instanziiert, wenn eine Methode dieser Klasse aufgerufen wird.

Kein Konfigurationsabruf beim Erstellen des CLI-Objekts — kein Fehler.

Mehr Details zum Proxy-Pattern findest du hier: Proxies.

Automatisierte Proxy-Injection vereinfacht den Prozess

Bei Projekten mit wenigen Extensions ist es nicht besonders schwierig, die problematischen CLI-Befehle ausfindig zu machen. Bei umfangreicheren Legacy-Projekten oder solchen mit vielen Drittanbieter-Extensions wird die Suche jedoch schnell zur Tortur.

Um Zeit zu sparen, haben wir eine Lösung entwickelt, die die Proxy-Injection automatisiert. Wir stellen vor: run-as-root/magento-cli-auto-proxy.

Dieses Package injiziert Proxy in alle __construct-Argumente von CLI-Befehlen, die für Proxying geeignet sind. Das Ergebnis: Keine Fehler mehr durch verfrühten Ressourcenzugriff — und als angenehmer Nebeneffekt eine schnellere Ausführung von php bin/magento und php bin/magento setup:install.

Schau dir die README für weitere Details an. Wir freuen uns über Feedback und Beiträge!

Zusammenfassung

Kurz zusammengefasst:

  • Unüberlegt erstellte CLI-Befehle können unerwartete Probleme verursachen — auch wenn sie auf den ersten Blick harmlos wirken.
  • Der Kern des Problems liegt oft in verfrühten Datenbankzugriffen, die zu einem klassischen "Henne-Ei"-Szenario führen, bei dem die System-Installation ins Stocken gerät.
  • Ein wesentlicher Fallstrick sind die CLI-Command-Konstruktoren, die zum falschen Zeitpunkt aufgerufen Chaos anrichten können.
  • Um diesen Herausforderungen zu begegnen, haben wir drei Leitprinzipien vorgestellt:
  1. Sei klug und vermeide ressourcenintensive Aufrufe in Konstruktoren.
  2. Sei vorbereitet und greife nicht auf Ressourcen zu, die möglicherweise nicht verfügbar sind.
  3. Behebe das Problem und nutze Proxies für problematischen Drittanbieter-Code.
  • Als Lösung zur Automatisierung haben wir das Package run-as-root/magento-cli-auto-proxy vorgestellt, das Proxy-Injections automatisiert und so eine effizientere und fehlerfreie Magento-Erfahrung ermöglicht.

Danke, dass du dir die Zeit genommen hast, diesen Artikel zu lesen. Ich freue mich über deine Fragen und Feedback.

Happy coding und... Long Live Magento! 😁

Deine Adobe Commerce CLI-Befehle optimieren?

Sprich mit Vlad, unserem Adobe Commerce-Experten, und verbessere deinen Entwicklungs-Workflow.

Buche jetzt deinen Termin

Weitere Beiträge

Technical
/images/blog/blog_INP_corewebvitals_thumbnail.webp
Jordy Scholing Avatar

Jordy Scholing

14.11.25

INP debuggen: Von DevTools zu RUM-Daten