- n8n version: Version 1.47.2
- Database (default: SQLite): default
- n8n EXECUTIONS_PROCESS setting (default: own, main): default
- Running n8n via (Docker, npm, n8n cloud, desktop app): npm
- Operating system: ubuntu
{
"errorMessage": "No data found for item-index: \"1\" [item 1]",
"errorDetails": {},
"n8nDetails": {
"itemIndex": 1,
"runIndex": 0,
"parameter": "command",
"time": "07/07/2024, 16:43:08",
"n8nVersion": "1.47.2 (Self Hosted)",
"binaryDataMode": "default",
"stackTrace": [
"ExpressionError: No data found for item-index: \"1\"",
" at Object.get (/usr/local/lib/node_modules/n8n/node_modules/n8n-workflow/src/WorkflowDataProxy.ts:409:14)",
" at Proxy.eval (eval at getFunction (/usr/local/lib/node_modules/n8n/node_modules/@n8n/tournament/src/index.ts:30:16), <anonymous>:9:74)",
" at Proxy.eval (eval at getFunction (/usr/local/lib/node_modules/n8n/node_modules/@n8n/tournament/src/index.ts:30:16), <anonymous>:16:7)",
" at Tournament.execute (/usr/local/lib/node_modules/n8n/node_modules/@n8n/tournament/src/index.ts:42:13)",
" at evaluateExpression (/usr/local/lib/node_modules/n8n/node_modules/n8n-workflow/src/ExpressionEvaluatorProxy.ts:92:10)",
" at Expression.renderExpression (/usr/local/lib/node_modules/n8n/node_modules/n8n-workflow/src/Expression.ts:349:29)",
" at Expression.resolveSimpleParameterValue (/usr/local/lib/node_modules/n8n/node_modules/n8n-workflow/src/Expression.ts:322:28)",
" at Expression.getParameterValue (/usr/local/lib/node_modules/n8n/node_modules/n8n-workflow/src/Expression.ts:544:16)",
" at getNodeParameter (/usr/local/lib/node_modules/n8n/node_modules/n8n-core/src/NodeExecuteFunctions.ts:2467:36)",
" at Object.getNodeParameter (/usr/local/lib/node_modules/n8n/node_modules/n8n-core/src/NodeExecuteFunctions.ts:3698:12)"
]
}
}
Hello! I’m running into a frustrating “No data found for item-index: ‘1’” error in my n8n workflow, and I’m struggling to understand why it’s happening. Here’s my setup:
Workflow Goal:
The workflow is designed to:
- Monitor a folder (
/var/www/run/work/
) for new ZIP archives containing PDFs. - Unzip each archive to a subfolder, renaming files to remove special characters.
- Extract text, images, and markdown from the PDFs.
- Optionally stitch multiple images per page into a single image.
Workflow Breakdown:
- Local File Trigger: Triggers the workflow when a new
.zip
file is added to the/var/www/run/work/
directory. - Execute Command (Python script:
hantera_zip_filer.py
):- Unzips the ZIP archive, handling special characters and streaming to minimize memory usage.
- Outputs a JSON object with details about the unzipped files and processing time.
- Function node (
jsonformating
): Parses the stdout JSON fromhantera_zip_filer.py
and restructures it for further processing. - Execute Command (Python script:
md_extrahera_bilder_fitz.py
):- Extracts text, images, and markdown from the PDFs within the unzipped folder.
- Outputs a JSON array containing results for each PDF processed.
- Function node (
jsonformating1
): Parses the JSON output frommd_extrahera_bilder_fitz.py
, potentially creating multiple items. - Execute Command (Python script:
sammanfoga_bilder.py
):- Stitches together multiple images on a single page, if necessary.
- Outputs a JSON array with results for each page processed, indicating whether images were stitched or not.
- Function node (
jsonformating2
): Parses the JSON output fromsammanfoga_bilder.py
. - Execute Command (
move_zip2done
): Moves the original ZIP archive to the/var/www/run/done/
folder. - Execute Command (
move_folder2done
): Moves the folder containing the extracted files to the/var/www/run/done/
folder. - clean up /work/ folder and remove the processed files
The Problem:
The stitch_img
node (Execute Command running sammanfoga_bilder.py
) is consistently throwing the error “No data found for item-index: ‘1’”, even though there is data available from the preceding “jsonformating” node, which outputs a single item.
Questions:
- Could someone help me understand why this error is occurring? Is it possible that a node in the workflow is expecting more items than it’s receiving, even though the initial trigger (Local File Trigger) is correctly configured for a single item (file)?
- How can I make this workflow more robust so that it handles cases where a node doesn’t produce output for a particular item or page? Should I use an “IF” node to check for empty data?
Any insights or suggestions would be highly appreciated. I’m still getting my bearings with n8n and would welcome any expert advice!
Please let me know if you need more details about my workflow or the Python scripts.
hantera_zip_fil.py
import os
import zipfile
import time
import sys
from unidecode import unidecode
def ersatt_aao_och_mellanslag(text):
"""Ersätt åäö (gemener och versaler) och mellanslag med _ i en textsträng."""
text = unidecode(text).lower()
text = text.replace(" ", "_")
return text
def hantera_zip_fil(zip_fil):
"""Byt namn på och unzippa en ZIP-fil, strömma filinnehållet."""
start_tid = time.time() # Starta tidmätning
rot, fil = os.path.split(zip_fil) # Hämta mappsökväg och filnamn
mappnamn = ersatt_aao_och_mellanslag(os.path.splitext(fil)[0])
utdata_mapp = os.path.join(rot, mappnamn)
if not os.path.exists(utdata_mapp):
os.makedirs(utdata_mapp)
with zipfile.ZipFile(zip_fil, 'r') as zip_ref:
for info in zip_ref.infolist():
if "__MACOSX" in info.filename:
continue
if info.filename.endswith(".pdf"):
try:
gammalt_filnamn = info.filename
nytt_filnamn = ersatt_aao_och_mellanslag(gammalt_filnamn)
# Strömma filinnehåll med 1MB bitar
with zip_ref.open(info, 'r') as infile, open(os.path.join(utdata_mapp, nytt_filnamn), 'wb') as outfile:
while True:
bit = infile.read(1048576) # Läs 1MB åt gången
if not bit:
break
outfile.write(bit)
except Exception as e:
print(f"Fel vid extrahering av fil {gammalt_filnamn}: {e}")
print(f"Unzippat: {zip_fil} till {utdata_mapp}")
# Byt namn på ZIP-filen *efter* uppackning
nytt_namn = os.path.join(rot, ersatt_aao_och_mellanslag(fil))
try:
os.rename(zip_fil, nytt_namn)
print(f"Bytte namn på: {zip_fil} till {nytt_namn}")
except Exception as e:
print(f"Fel vid namnbyte av {zip_fil}: {e}")
slut_tid = time.time() # Stoppa tidmätning
print(f"Tiden det tog att packa upp filerna: {slut_tid - start_tid} sekunder")
if __name__ == "__main__":
if len(sys.argv) > 1:
zip_fil = sys.argv[1]
hantera_zip_fil(zip_fil) # Bearbeta endast den angivna filen
else:
print("Fel: Ingen filsökväg angiven.")
md_extrahera_bilder_fitz.py
import os
import time
import sys
import pymupdf4llm
import fitz
import json
def ersatt_aao_och_mellanslag(text):
"""Ersätt åäö (gemener och versaler) och mellanslag med _ i en textsträng."""
text = text.lower()
ersattningar = {
"å": "a",
"ä": "a",
"ö": "o",
" ": "_" # Ersätt mellanslag med _
}
for tecken, ersattning in ersattningar.items():
text = text.replace(tecken, ersattning)
return text
def extrahera_data(mapp):
"""Extrahera text och bilder från alla PDF-filer i en specifik mapp."""
resultat = []
start_tid = time.time()
# Kontrollera om mappen existerar
if os.path.exists(mapp):
for filnamn in os.listdir(mapp):
if filnamn.endswith(".pdf"):
pdf_fil = os.path.join(mapp, filnamn)
rot, fil = os.path.split(pdf_fil)
dokumentnamn = ersatt_aao_och_mellanslag(os.path.splitext(fil)[0])
# Tidmätning för Markdown-extraktion
start_tid_markdown = time.time()
try:
md_text = pymupdf4llm.to_markdown(pdf_fil, write_images=False)
with open(os.path.join(rot, f"{dokumentnamn}.md"), "w", encoding="utf-8") as f:
f.write(md_text)
slut_tid_markdown = time.time()
# Lägg till information i resultatlistan
resultat.append({
"action": "extract_markdown",
"pdf_file": pdf_fil,
"markdown_file": os.path.join(rot, f"{dokumentnamn}.md"),
"duration": slut_tid_markdown - start_tid_markdown
})
except Exception as e:
slut_tid_markdown = time.time()
resultat.append({
"action": "extract_markdown",
"pdf_file": pdf_fil,
"error": str(e),
"duration": slut_tid_markdown - start_tid_markdown
})
# Tidmätning för bildextration
start_tid_bilder = time.time()
try:
# Extrahera bilder med PyMuPDF (fitz)
doc = fitz.open(pdf_fil)
for i, sida in enumerate(doc):
bildlista = sida.get_images(full=True)
for j, img in enumerate(bildlista):
xref = img[0] # Bildens referensnummer
basbild = doc.extract_image(xref)
bilddata = basbild["image"]
tillägg = basbild["ext"]
# Anpassa filnamnet efter behov
filnamn = f"{rot}/{dokumentnamn}_sida_{i+1}_bild_{j+1}.{tillägg}"
if bilddata:
with open(filnamn, "wb") as f:
f.write(bilddata)
slut_tid_bilder = time.time()
resultat.append({
"action": "extract_images",
"pdf_file": pdf_fil,
"duration": slut_tid_bilder - start_tid_bilder
})
except Exception as e:
slut_tid_bilder = time.time()
resultat.append({
"action": "extract_images",
"pdf_file": pdf_fil,
"error": str(e),
"duration": slut_tid_bilder - start_tid_bilder
})
else:
print(f"Fel: Mappen '{mapp}' hittades inte.")
slut_tid = time.time()
resultat.append({
"action": "total_duration",
"duration": slut_tid - start_tid
})
# Skriv ut resultatlistan som JSON
print(json.dumps(resultat))
if __name__ == "__main__":
if len(sys.argv) > 1:
mapp_med_pdf_filer = sys.argv[1] # Hämta mappsökvägen från argument
extrahera_data(mapp_med_pdf_filer)
else:
print("Fel: Ingen mappsökväg angiven.")
sammanfoga_bilder.py
import os
import subprocess
import json
import sys
def sammanfoga_bilder_for_sida(bildmapp, sidnummer, max_bilder=3):
"""Sammanfogar bilder för en specifik sida med ImageMagick."""
bildfiler = [
os.path.join(bildmapp, f)
for f in os.listdir(bildmapp)
if f"_sida_{sidnummer}_bild_" in f and f.lower().endswith((".png", ".jpg", ".jpeg"))
]
# Sortera bildfiler baserat på sidnummer och bildnummer
bildfiler.sort(key=lambda f: (int(f.split("_sida_")[1].split("_bild_")[0]),
int(f.split("_bild_")[1].split(".")[0])))
if len(bildfiler) >= max_bilder: # Sammanfoga om det finns tillräckligt med bilder
try:
utdatafil = os.path.join(bildmapp, f"sida_{sidnummer}_sammanfogad.png")
subprocess.run(
["convert", *bildfiler, "-append", utdatafil],
check=True
)
for fil in bildfiler:
try:
os.remove(fil)
except Exception as e:
print(f"Fel vid borttagning av fil {fil}: {e}")
return {"success": True, "message": f"Bilder för sida {sidnummer} sammanfogade till {utdatafil}."}
except subprocess.CalledProcessError as e:
return {"success": False, "message": f"Fel vid sammanfogning: {e}"}
else:
return {"success": True, "message": f"Inga bilder att sammanfoga för sida {sidnummer}."}
def bearbeta_mapp(mapp, max_bilder):
"""Bearbetar en mapp för att sammanfoga bilder."""
alla_resultat = []
if os.path.basename(mapp) == "__MACOSX":
return alla_resultat
# Identifiera alla unika sidnummer från filnamnen i mappen
sidnummer = set()
for filnamn in os.listdir(mapp):
if "_sida_" in filnamn:
try:
# Extrahera sidnummer från filnamnet
sidnummer_str = filnamn.split("_sida_")[1].split("_bild_")[0]
sidnummer.add(int(sidnummer_str))
except (IndexError, ValueError):
print(f"Varning: Ogiltigt filnamn: {filnamn}")
continue
# Sammanfoga bilder för varje unikt sidnummer
for s in sidnummer:
resultat = sammanfoga_bilder_for_sida(mapp, s, max_bilder) # Skicka mapp direkt
alla_resultat.append(resultat)
print(f"alla_resultat: {alla_resultat}")
return alla_resultat
if __name__ == "__main__":
if len(sys.argv) > 1:
mapp_att_bearbeta = sys.argv[1]
max_bilder = 3 # Hårdkodat till 3 bilder
alla_resultat = bearbeta_mapp(mapp_att_bearbeta, max_bilder)
print(json.dumps(alla_resultat))
else:
print("Fel: Mappsökväg saknas.")
testfile https://file.io/8wRYPUBBrVZ9