Shopify Liquid debuggen mit Claude

Zuletzt aktualisiert
•
Von Experten geprüft
•
5 Min. Lesezeit

Key Takeaways

  • Um Shopify Liquid mit Claude zu debuggen, füge drei Dinge ein: das Template, den genauen Fehler und das Objekt-Schema. Fehlt eines davon, rät Claude nur.
  • Die meisten Liquid-Bugs sind still. Ein nil-Objekt gibt nichts aus, daher bleibt die Seite leer, anstatt einen Fehler zu werfen.1
  • Whitespace, Filter-Reihenfolge und Loop-Scopes verursachen Bugs, die wie Datenprobleme aussehen, aber eigentlich Syntaxprobleme sind.2
  • Claude ist stark bei Template-Logik und Schema-JSON. Schwächen gibt es beim Live-Theme-Status und von Apps injiziertem Code, den Claude nicht sehen kann.
  • Validiere jeden Fix anhand der Shopify Liquid-Referenz, bevor du ihn pushst. Vertraue keinem Output, der keine Quelle nennt.

Um Shopify Liquid mit Claude zu debuggen, musst du den gleichen Kontext liefern, nach dem auch ein Senior Theme-Entwickler fragen würde. Liquid schlägt im Stillen fehl. Ein fehlendes Objekt löst keine Exception aus – es wird einfach nichts gerendert.1 Das macht die Kategorie „Warum ist diese Section leer?“-Bugs schwer allein anhand eines Screenshots nachzuvollziehen. Dieser Guide behandelt die häufigsten Liquid-Bugs, den genauen Kontext, den Claude benötigt, Prompt-Muster, mit denen du Fehler schnell eingrenzen kannst, und die Grenzen der Zuverlässigkeit von Claude.

Informationen zur Einrichtung der Plattform findest du in unserem Shopify AI Toolkit mit Claude Code Setup-Guide.


Warum du uns vertrauen kannst

Jacques hat über 15 Jahre Entwicklungserfahrung und hat mit hunderten Shopify-Stores zusammengearbeitet. Wir haben Fudge, den KI-Operator für Shopify-Stores, entwickelt – mit einer 4.9-Bewertung und dem Built for Shopify-Badge. Wir debuggen Liquid täglich, sowohl manuell als auch mit KI-Unterstützung.


Warum Liquid-Bugs schwer zu erkennen sind

Liquid wurde so entwickelt, dass es auf einer Live-Storefront im Zweifel sicher (fail-safe) fehlschlägt. Genau diese Design-Entscheidung macht die Sprache aber schwer zu debuggen.

In Liquid gibt es nur zwei „falsy“ Werte: nil und false. Alles andere – leere Strings, die Zahl Null, leere Arrays – ist „truthy“.1 Eine Bedingung, von der du im Code vielleicht denkst, sie würde vor „fehlenden Daten“ schützen, geht oft trotzdem durch, wenn die Daten zwar leer, aber physisch vorhanden sind.

Ein Tag oder Output, der nil zurückgibt, wird schlichtweg nicht ausgegeben und als false behandelt.1 Es gibt dabei keinen Stacktrace. Die Section wird einfach leer gerendert und du darfst raten, welches Objekt stattdessen auf nil zurückfiel.

Das ist der Hauptgrund, warum das Debuggen von Liquid mit Claude so gut funktioniert, sofern man es richtig angeht. Du verlangst von Claude nicht, eine Exception abzufangen, sondern du bittest das Tool, schlusszufolgern, welches Objekt in einer Chain ins Leere gelaufen sein könnte.


Welchen Kontext Claude braucht, um Liquid zu debuggen

Die wichtigste Zutat für einen guten Fix ist der Kontext, den du reingibst. Übermittle Claude jedes Mal diese drei Dinge:

1. Das Template oder Snippet. Füge den kompletten Block ein, nicht nur kleine Fragmente. Scope-Fehler verstecken sich nämlich meist in genau den Zeilen, die du weggelassen hast.

2. Den genauen Fehler oder das Symptom. „Translation missing: en.products.price“ bringt viel mehr als „der Preis ist kaputt.“ Wenn es keinen sichtbaren Fehler gibt, beschreibe ganz exakt, was du vor dir hast: z. B. eine leere Section, eine falsche Block-Anzahl, doppelte Elemente.

3. Das Objekt-Schema. Sag Claude, mit welchem Objekt du eigentlich arbeitest – product, collection, cart –, damit die KI Feldnamen anhand der echten Shopify-Dokumentation validieren kann, anstatt munter Felder zu erfinden.

Ein Beispiel für einen Prompt, der funktioniert:

Hier ist meine Section. Der Preisblock bleibt bei einigen Produkten leer,
bei anderen wiederum nicht. Das Objekt ist `product`. Was könnte hier auf nil auflösen?

[füge hier den kompletten Liquid-Code der Section ein]

Schickst du das Schema nicht mit, referenziert Claude unter Umständen ein Feld, das es für dieses Objekt gar nicht gibt. Fehlt das komplette Template, kann Claude den Loop nicht sehen, der den globalen Variablen-Scope verändert hat.


Häufige Liquid-Bugs und wie du sie behebst

Nil und undefinierte Objekte

Das ist der absolut häufigste Liquid-Bug. Du greifst auf ein Attribut an einem Objekt zu, das nil ist, und schon verschwindet der gesamte Output unsichtbar.1

Auch der empty-Status spielt eine Rolle. Eine gelöschte Ressource oder eine Einstellung ohne zugewiesenen Wert wirft ein empty-Objekt zurück, das du prüfen solltest, bevor du Attribute daraus lesen willst.1

Vorher:

<span>{{ product.metafields.custom.subtitle.value }}</span>

Wenn dieses Metafield nicht gesetzt ist, löst sich diese Sub-Chain in Luft bzw. nil auf und druckt nichts aus. Bitte Claude wie folgt um eine Absicherung:

Nachher:

{% if product.metafields.custom.subtitle != blank %}
  <span>{{ product.metafields.custom.subtitle.value }}</span>
{% endif %}

Ein guter Prompt für Claude wäre: „Welche Links in dieser Attribut-Chain können eigentlich nil sein, und wie baue ich für jeden einzelnen ein Guard ein?“

Scope-Probleme innerhalb von Loops

Jede for-Schleife hat ein forloop-Objekt, und es existiert nur innerhalb der Schleife: Wenn du es außerhalb ausliest, erhältst du nil.3 Variablen, die du innerhalb der Schleife mit assign zuweist, verhalten sich anders. Sie behalten den Wert der letzten Iteration nach dem Ende der Schleife bei, was eine häufige Ursache für falsche Zählungen ist. Snippets, die mit render aufgerufen werden, können die Variablen des übergeordneten Templates gar nicht sehen.

Wenn deine Zählung falsch ist oder deine „Letztes Element“-Logik fehlschlägt, liegt der Bug meistens am Scope. Füge die komplette Schleife ein und bitte Claude, zurückzuverfolgen, wo jede Variable gesetzt und ausgelesen wird.

Whitespace-Kontrolle

Liquid gibt Whitespace (Leerzeichen/Umbrüche) exakt dort aus, wo deine Tags sitzen. Überflüssiger Whitespace zerschießt dir manchmal Layouts, bläht das HTML unnötig auf und kann sogar JSON-Blobs kaputt machen, die du mit Liquid händisch aufbaust.

Indem du Bindestriche in dein Liquid-Tag einfügst, kannst du Whitespace entfernen lassen, der sonst gerendert wird. Wichtig: Du kannst den Bindestrich beim öffnenden oder beim schließenden Tag anhängen, um den Whitespace gezielt nur von einer Seite wegzustrippen.2

Vorher:

{% for tag in product.tags %}
  {{ tag }}
{% endfor %}

Nachher:

{%- for tag in product.tags -%}
  {{- tag -}}
{%- endfor -%}

Frag Claude: „Dieser Block gibt störenden Whitespace aus, der mein Inline-Layout zerschießt. An welche Stellen müssen die Bindestriche zur Whitespace-Kontrolle (Whitespace-Control-Hyphens) gesetzt werden?“

Reihenfolge beim Filter-Chaining

Auf einen Output können mehrere Filter angewendet werden, und sie werden von links nach rechts abgearbeitet.4 Die Reihenfolge ist nicht nur Kosmetik. Ein Filter, der einen String erwartet, wird fehlschlagen, wenn ein vorheriger Filter den Wert bereits in ein Array umgewandelt hat.

Vorher:

{{ product.title | split: ' ' | upcase }}

upcase erwartet einen String, aber split hat bereits ein Array zurückgegeben. Ändere die Reihenfolge, sodass upcase vor split ausgeführt wird: {{ product.title | upcase | split: ' ' }}.

Frag Claude: „Verfolge diese Filter-Chain von links nach rechts. Welchen Typ empfängt und liefert jeder Filter?“

Spar dir das Liquid-Debugging komplett.
Kostenlose Testversion starten

Pagination-Limits

for-Loops haben Obergrenzen in Shopify. Maximal 50 Iterationen macht ein einfacher for-Loop mit; für alles, was darüber hinausgeht, musst du zwingend das paginate-Tag nutzen.3

Das paginate-Tag spaltet längere Arrays über mehrere Seiten hinweg auf. Die dafür angegebene page_size muss bei einem Wert zwischen 1 und 250 liegen.5 Das Ganze hat jedoch ebenfalls ein striktes Hardlimit: Du kannst die Pagination nur bis zum 25.000sten Item betreiben – danach ist Schluss.5 Extrem große Arrays müssen deshalb vorab zwingend gefiltert werden.

Stoppt dein Collection-Loop also sang- und klanglos stillschweigend nach exakt 50 Produkten, weißt du Bescheid: Du bist ins Iterationslimit gerasselt – das ist dann kein Datenproblem. Frag Claude einfach, ob er deinen Loop mit einem gültigen page_size-Parameter in ein sauberes paginate wrappen kann.

Section- und Block-Schema-Fehler

Fehler im Schema schreien glücklicherweise nicht erst beim Rendern, sondern werfen schon während der Bearbeitungszeit (Edit-Time) Fehler, was die Jagd nach Schema-Bugs vergleichsweise leicht macht.

Das {% schema %} selbst darf nur durchweg valides JSON enthalten. Setting-IDs müssen – genau wie alle Block-Namen und Block-Typen – in jeder einzelnen Section einmalig (unique) sein. Doppelt vergebene IDs oder Sections mit mehr als nur einem einzigen (und erlaubten) {% schema %}-Tag enden stets in einem fiesen Syntax-Error für deinen Theme-Editor.6

Standardmäßig liegt das Limit für Blöcke in einer Section bei maximal 50. Man kann das durch max_blocks sogar noch weiter künstlich einschränken, wenn man das möchte. Eingebrachte rein statische Blöcke zählen nicht gegen dieses Cap.6

Paste schlichtweg den Schema-Block zusammen mit dem exakten Bug aus deinem Editor ein und lass Claude dieses JSON-Paket gründlich validieren und gegen doppelt vergebene IDs prüfen. Solche isolierten Aufgaben zählen zu den mit Abstand stärksten Seiten der KI, da Schema-Pakete komplett in sich selbst geschlossen funktionieren – null Abhängigkeiten zu externen Live-States im Store nötig.

Wie man das alles jedoch schon von Stunde Null an formvollendet aufzieht? In unserem neuen Guide zeigen wir dir, wie genau du eine Custom-Section in Shopify baust.

Fehlende Translation-Keys

Kann der t-Filter einen gesuchten String-Key in der gerade aktiven Locale-File nicht ausfindig machen, spuckt der Tag unweigerlich den unschönen Output Translation missing: [locale].[key] aufs Frontend aus, statt wie Liquid sonst gewohnt still und unsichtbar zu sterben.7

Solche Key-Pfade laufen über reguläre Dot-Notationen, welche nahtlos in Shopify’s JSON-Schema abgebildet werden. Aber Achtung: In Liquid selbst wiederum müssen diese in Single Quotes verpackt sein.7 Ein Code-Schnipsel à la 'products.price' sucht somit erst gezielt im obersten Ast nach products und anschließend nach dem tiefergreifenden Knoten price in der Locale-JSON-Struktur.

Vorher:

{{ 'products.prise' | t }}

Ein banaler Typo im angegebenen Key verpasst dir sonst prompt einen formschönen Translation missing: en.products.prise Fehler auf die Seite. Füge am besten immer sowohl die Liquid-Zeile an sich als auch die fragliche Locale-JSON für Claude ein. Die KI vergleicht deinen referenzierten Object-Path dann eins-zu-eins gegen die Dateistruktur im Backend und findet jede Ungereimtheit.


Prompt-Patterns, die einen Bug isolieren

Grenze zuerst den Bereich ein

Schmeiß Claude keinen ewig scrollenden, tausendzeiligen Code um die Ohren und frag ungeduldig: „Was ist falsch?“ Reproduziere den Fehler so klein wie nur eben möglich. Isolier den Part, um den es geht, schneide ihn aus und paste stattdessen lieber den Part rein. Nur gezielter (und kompakter) Input führt zu gezielten Antworten.

Lass Claude nachdenken, bevor es Code anpasst

Ein guter Prompt: „Bevor du überhaupt anfängst zu ändern – liste mir doch bitte kurz und sauber auf, welche Variablen oder Objekte hier im Block am ehesten Out of Scope sind oder auf nil abprallen könnten.“ Das triggert bei Claude das kritische Diagnostizieren, bevor der erste Zeilenumbruch gepusht wird. Es zwingt den Bot zum Überlegen und bereitet dir ein gut sichtbares Buffet an den potenziellsten Knackpunkten auf, das du schnell im Kopf via „Sanity-Check“ abklopfen kannst.

Gib ihm die zugehörige Datenstruktur mit

Hat ein product etwa gerade wirklich überhaupt keine Varianten hinterlegt, oder ist das angeforderte Field von vornherein ein ungefülltes nil-Metafield, dann sag der KI das auch. Claude kann deine tiefsten Live-Daten logischerweise nicht quer durch alle Layer ausleuchten. Allein deine treffende Beschreibung, wie die Daten aktuell aufgebaut sind, ersetzt den unsicheren Blindflug der KI durch verlässliche Gewissheit.

Immer nur eine Änderung auf einmal

Frag ganz strikt nach nur einem einzigen Fix ab. Bau ihn ein, teste ihn selbst und wenn das geht – ab zum nächsten Schritt weiter. Bundelst du Edit-Requests gleich palettenweise, verlierst du enorm schnell den essenziellen Überblick. Welche Änderungen deiner 20 gepushten Zeilen haben denn jetzt wirklich den eigentlichen Bug vernichtet, und welche haben im Umkehrschluss gerade eben einen völlig anderen mit in dein Frontend gegossen?

Ausführlichere Ansätze und beständige Routinen rund um Theme-Editor-Modifizierungen findest du unter Wie man ein Shopify-Theme sicher bearbeitet.


Einen Fix mit der Liquid-Referenz validieren

Jeder KI-Fix bleibt solange reine Spekulation (und eine Hypothese), bis du ihn höchstselbst auf Validität überprüft hast. Zwei essenzielle Gewohnheiten behüten dich vor bösen Überraschungen beim Deployment:

Bestätige, dass jedes referenzierte Object und jeder Filter auf Shopify-Seite definitiv so exisitiert. Nutzen KI-generierte Codeblöcke ein frei erfundenes Feld á la product.custom_price, nutz den Shopify-Liquid-Referenz-Guide, um das Gegenzuprüfen. Blind erfundene Felder der LLMs verenden als flaues nil und reaktivieren exakt den miesen Null-Output Fehler, mit dem du ins Rennen gegangen bist.1

Checke Filter-Funktionsweisen, nicht nur die Filter-Namen an sich. Bestätige lieber zweimal, dass Filter-Element X auch wirklich als zulässigen Input-Type den Typ akzeptiert, den deine ausgeführte Chain vorab dorthin piped. Liquid-Filter iterieren von String nach rechts durch und werfen jeden gefilterten Batch schnurstracks als nächsten Input in den nachfolgenden Knoten.4

Das offizielle Shopify AI Toolkit prüft Liquid Code sogar teilweise schon vollautomatisch live gegen die implementierten Schemas ab und schmilzt diese nervigen Review-Stufen merkbar ein. Dein kritisches, aufmerksames Review deines reinen Code-Diffs ersetzt aber trotzdem nach wie vor nichts und niemand zu 100%.


Wo Claude an seine Grenzen stößt

Claude ist stark bei Template-Logik, Filter-Chains und Schema-JSONs. Aber es gibt klare blinde Flecken.

Live-Theme-Status. In einem Chat sieht Claude nur, was du einfügst. Ein Bug, der nur bei einer bestimmten Theme-Editor-Einstellung auftritt, ist für Claude also unsichtbar, bis du diesen Zustand beschreibst. Wenn du das Theme mit der Shopify CLI in Claude Code ziehst, kann es templates/*.json und settings_data.json lesen, die die Section-Platzierung und Editor-Einstellungen enthalten. Aber es kann immer noch keinen Code sehen, den Apps zur Laufzeit injizieren.

App-injizierter Code. Viele Storefront-Bugs stammen von Code, den eine App zur Laufzeit (Runtime) über den Theme-Editor oder content_for_header injiziert. Claude kann keinen Code lesen, der ihm nie gezeigt wurde. Wenn ein Bug nur auftritt, wenn eine bestimmte App aktiviert ist, ist diese App verdächtig und du musst das selbst ansprechen.

Datenabhängige Bugs. Eine Section, die nur bei Produkten ohne Varianten oder bei einem nil-Metafield kaputtgeht, ist ein Datenstruktur-Problem. Claude kann deinen Katalog nicht abfragen. Es zieht seine Schlüsse aus den Daten, die du beschreibst.

Hier ändert ein KI-Operator, der direkt in den Store integriert ist, das Bild komplett. Fudge, der KI-Operator für Shopify-Stores, arbeitet direkt in Shopify und liest den Code deines Themes, deine Produkte und Brand-Infos, bevor er etwas ändert – einschließlich der Blöcke, die deine Apps hinzufügen, und der Änderungen, die deine Entwickler vorgenommen haben. Dadurch kennt er den Store-Status, der einem allgemeinen Coding-Assistenten fehlt. Seine Fixes kommen als Entwürfe mit einer funktionierenden Vorschau, sodass du sie an echten Produkten überprüfen kannst, bevor Käufer sie sehen. Und der Shopify Store Editor behält die Version, die durch jede Änderung ersetzt wurde, falls du einen Rollback machen musst. Mehr zu diesem allgemeinen Wandel in der Arbeitsweise findest du in unserem Beitrag über AI-first Shopify-Entwicklung.


Ein wiederholbarer Debugging-Loop

  1. Reproduziere den Bug im kleinsten fehlerhaften Block.
  2. Sammle das Template, den genauen Fehler oder das Symptom und das Objekt-Schema.
  3. Bitte Claude um eine Diagnose, bevor du bearbeitest – lass auflisten, was nil oder out of scope sein könnte.
  4. Wende einen Fix an und teste ihn isoliert.
  5. Validiere jedes Objekt und jeden Filter mit der Shopify Liquid-Referenz.
  6. Pushe als unveröffentlichtes Theme zuerst, niemals direkt ins Live-Theme.

Dieser Loop verwandelt das Silent-Failure-Modell von Liquid von einem Risiko in eine Checkliste.

Für tiefergehende Arbeiten an Custom Logic, siehe Wie man Custom Liquid Logic in Shopify hinzufügt.


FAQ

Warum wird meine Shopify-Section ohne Fehlermeldung leer gerendert?

Liquid schlägt stillschweigend fehl (fails silently). Ein Tag oder Output, der nil zurückgibt, gibt nichts aus und wird als false behandelt. Es gibt also keinen Stack Trace – die Section wird einfach leer gerendert. Die häufigste Ursache ist eine Objekt- oder Attribut-Chain, die zu nil aufgelöst wurde. Füge die komplette Section und den Objektnamen in Claude ein und frage, welche Links in der Chain nil sein könnten.

Wie gebe ich Claude genug Kontext, um Liquid zu debuggen?

Füge jedes Mal drei Dinge ein: das vollständige Template oder Snippet, den genauen Fehler oder das Symptom (z. B. "Translation missing: en.products.price") und das Objekt, mit dem du arbeitest (product, collection, cart). Ohne das Objekt-Schema verweist Claude möglicherweise auf Felder, die nicht existieren. Ohne das komplette Template kann es die Schleife nicht sehen, die den Scope der Variablen geändert hat.

Warum stoppt meine Liquid for-Schleife bei 50 Elementen?

Das ist das eingebaute Limit. Eine for-Schleife führt maximal 50 Iterationen aus. Um weiterzugehen, musst du die Schleife in den paginate-Tag packen, wobei page_size zwischen 1 und 250 liegen muss. Du kannst bis zum 25.000sten Element paginieren und nicht weiter. Wenn eine Collection-Schleife stillschweigend abbricht, liegt das am Iterationslimit, nicht an einem Datenproblem.

Was bedeutet "Translation missing" in Shopify Liquid?

Der t-Filter konnte deinen Key in der aktiven Locale-Datei nicht finden, also rendert er "Translation missing: [locale].[key]" auf der Seite, anstatt stillschweigend fehlzuschlagen. Meistens ist es ein Tippfehler im Key-Pfad in der Dot-Notation oder ein Key, der in der Locale-JSON fehlt. Keys müssen in einfache Anführungszeichen gesetzt werden. Füge sowohl die Liquid-Zeile als auch die Locale-JSON ein, damit Claude den Key-Pfad abgleichen kann.

Kann Claude meinen Live-Shopify-Theme- und App-Code sehen?

In einem Chat, nein: Claude sieht nur, was du einfügst. Zieh dir das Theme mit der Shopify CLI in Claude Code und es kann templates/*.json und settings_data.json lesen, die die Section-Platzierung und Theme-Editor-Einstellungen enthalten. Aber es kann immer noch keinen Code sehen, den eine App zur Laufzeit über content_for_header injiziert. Wenn ein Bug nur bei einer aktivierten App auftritt, musst du diesen Zustand beschreiben.

Wie hindere ich Claude daran, Liquid-Felder zu erfinden, die nicht existieren?

Validiere jedes Objekt und jeden Filter, den es verwendet, mit der Shopify Liquid-Referenz, bevor du pushst. Erfundene Felder wie product.custom_price lösen sich zu nil auf und bringen den Blank-Output-Bug zurück. Bitte Claude, das verwendete Objekt zu zitieren, und überprüfe, ob Filter den Eingabetyp akzeptieren, den sie erhalten, da Filter von links nach rechts angewendet werden.

Warum ändert die Neuordnung meiner Liquid-Filter den Output?

Filter werden von links nach rechts angewendet und jeder übergibt seinen Output an den nächsten. Wenn ein Filter einen String erwartet, aber ein vorheriger Filter bereits ein Array zurückgegeben hat, schlägt es fehl. Zum Beispiel übergibt split vor upcase an upcase ein Array anstelle eines Strings. Bitte Claude, die Chain zu verfolgen und zu notieren, welchen Typ jeder Filter empfängt und zurückgibt.

Jacques's signature
Bearbeite deine Shopify-Storefront ohne Liquid debuggen zu müssen.

Footnotes

  1. Shopify Liquid Basics – nil, empty und truthy/falsy Verhalten. https://shopify.dev/docs/api/liquid/basics ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7

  2. Shopify Liquid Basics – Whitespace-Control mit Bindestrichen. https://shopify.dev/docs/api/liquid/basics ↩ ↩2

  3. Shopify Liquid for-Tag – 50-Iterationen-Limit und forloop-Objekt. https://shopify.dev/docs/api/liquid/tags/for ↩ ↩2

  4. Shopify Liquid Filter – Pipe-Syntax und Links-nach-rechts-Chaining. https://shopify.dev/docs/api/liquid/filters ↩ ↩2

  5. Shopify Liquid paginate-Tag – page_size-Bereich und 25.000-Elemente-Grenze. https://shopify.dev/docs/api/liquid/tags/paginate ↩ ↩2

  6. Shopify Section-Schema – gültiges JSON, eindeutige IDs und das 50-Blöcke-Limit. https://shopify.dev/docs/storefronts/themes/architecture/sections/section-schema ↩ ↩2

  7. Shopify translate (t) Filter – „Translation missing“-Verhalten und Key-Mapping. https://shopify.dev/docs/api/liquid/filters/translate ↩ ↩2

You might also be interested in

Jacques Blom
Jacques Blom
CTO bei Fudge.