Workflow review
invoice_to_slack
Needs a human decision (2)
FlowGuard could not apply these fixes safely, so the fixed workflow leaves them unchanged.
Summarize Invoice· Batch all invoice summaries into a single LLM call, or replace the LLM with a Set node using n8n expressions (vendor/amount/currency/due_date are structured fields that need no AI formatting).Fetch Open Invoices· Add a deduplication node or store the IDs of already-posted invoices (e.g. in a database or n8n static data) and filter them out before the loop.
| Severity | Category | Node | Issue and fix | Status |
|---|---|---|---|---|
| critical | security | Fetch Open Invoices | Query parameter 'api_key' contains the literal value 'sk-FAKE-DEMO-KEY-000000'; hard-coded credentials are exposed to anyone with workflow access. Fix: Remove the literal value and use an n8n credential reference (e.g. httpQueryAuth or httpHeaderAuth) instead. | Fixed |
| high | cost | Summarize Invoice | LLM node is inside a SplitInBatches loop, making one API call per invoice per hourly run; a backlog of open invoices or a large invoice count will multiply costs linearly. Fix: Batch all invoice summaries into a single LLM call, or replace the LLM with a Set node using n8n expressions (vendor/amount/currency/due_date are structured fields that need no AI formatting). | Manual |
| high | reliability | Fetch Open Invoices | The hourly schedule fetches all open invoices with no deduplication; invoices that remain open across runs will be re-posted to the Slack approval channel every hour, generating duplicate messages. Fix: Add a deduplication node or store the IDs of already-posted invoices (e.g. in a database or n8n static data) and filter them out before the loop. | Manual |
| medium | docs | (workflow) | The workflow has no sticky notes and no node notes; its purpose, owner, and required credentials are undocumented. Fix: Add a stickyNote describing the workflow's purpose, trigger, owner, and credentials needed (billing API key, OpenAI, Slack). | Fixed |
Fixed workflow
flowchart LR
n0["Hourly Schedule"]
n1["Fetch Open Invoices"]
n2["Split Invoices"]
n3["Loop Over Invoices"]
n4["Summarize Invoice"]
n5["Post for Approval"]
n0 --> n1
n1 --> n2
n2 --> n3
n3 --> n4
n4 --> n5
n5 --> n3
classDef red fill:#fdecea,color:#8a1c12,stroke:#d0402b,stroke-width:1.5px
classDef orange fill:#fdf0e3,color:#7a3a06,stroke:#d9731a,stroke-width:1.5px
classDef yellow fill:#fbf5dc,color:#5e4b05,stroke:#b8960f,stroke-width:1.5px
classDef blue fill:#e8f0fb,color:#153e75,stroke:#3d74c4,stroke-width:1.5px
classDef clean fill:#f6f7f9,color:#2b3139,stroke:#c3c8cf
class n0 clean
class n1 red
class n2 clean
class n3 clean
class n4 orange
class n5 clean