@awesomate/hosting-mcp
Version:
Awesomate MCP server — lets Claude manage your Awesomate WordPress hosting, plan, limits, n8n automations, and build Node/static apps + databases
696 lines (566 loc) • 15.9 kB
Markdown
<!--
VENDORED from n8n-builder@d293559 (n8n-validation-expert/FALSE_POSITIVES.md) — DO NOT EDIT HERE.
Edit the source in ~/Projects/n8n-builder, then re-run:
node mcp/scripts/sync-n8n-references.mjs --write
Awesomate platform overrides — where this file conflicts with
../platform-notes.md, platform-notes wins:
- $env is BLOCKED fleet-wide → use {{ $vars.key || 'fallback' }}
- Task runners are ON → no $helpers in Code nodes; use HTTP Request nodes
- Webhook payloads live at $json.body
- saveExecutionProgress must stay false
-->
# False Positives Guide
When n8n warnings are acceptable and how to handle them.
## What Are False Positives?
**Definition**: Warnings that are technically "issues" but acceptable - or plain incorrect - in your specific use case.
**Key insight**: Not all warnings need to be fixed!
Many warnings are context-dependent: a large share of them are acceptable in specific use cases, and some are simply wrong about your workflow.
## Philosophy
### ✅ Good Practice
```
1. Read every warning in the editor / review output
2. Fix all ERRORS
3. Review each WARNING
4. Decide if acceptable for your use case
5. Document why you accepted it
6. Activate with confidence
```
### ❌ Bad Practice
```
1. Ignore all warnings blindly
2. Skip the review entirely to avoid warnings
3. Activate without understanding risks
```
## Structural False Positives
These aren't judgment calls - the warning itself is wrong about your workflow.
### A. Community/Custom Nodes Reported as Unknown
**Warning**:
```
Unknown node type: n8n-nodes-zernio.late
```
**Status**: False positive when the target instance has the community package installed
**Why it occurs**: Community and custom nodes (`CUSTOM.*`, `n8n-nodes-*`) can't be recognized outside the instance that has them - reviewing exported JSON elsewhere flags them as unknown.
**What to do**: Confirm the package is installed on the target instance; if so, ignore. Only treat as an error if the node type is a typo or the package is genuinely missing.
### B. Cycle-Based Polling Flagged as Circular Dependency
**Warning**:
```
Circular dependency detected: Check Status → Wait → Check Status
```
**Status**: False positive for intentional polling loops
**Why it occurs**: Structural review flags any cycle, but loop-back polling (Wait → check status → IF not done → loop back) is a legitimate pattern.
**What to do**: Ignore if the loop has a clear exit condition (IF branch that leaves the loop, max-attempts counter). Fix only if there's no way out of the cycle.
## Common Context-Dependent Warnings
### 1. Missing Error Handling
**Warning**:
```
No error handling configured
Suggestion: Add continueOnFail: true and retryOnFail: true
```
#### When Acceptable
**✅ Development/Testing Workflows**
```javascript
// Testing workflow - failures are obvious
{
"name": "Test Slack Integration",
"nodes": [{
"type": "n8n-nodes-base.slack",
"parameters": {
"resource": "message",
"operation": "post",
"channel": "#test"
// No error handling - OK for testing
}
}]
}
```
**Reasoning**: You WANT to see failures during testing.
**✅ Non-Critical Notifications**
```javascript
// Nice-to-have notification
{
"name": "Optional Slack Notification",
"parameters": {
"channel": "#general",
"text": "FYI: Process completed"
// If this fails, no big deal
}
}
```
**Reasoning**: Notification failure doesn't affect core functionality.
**✅ Manual Trigger Workflows**
```javascript
// Manual workflow - user is watching
{
"nodes": [{
"type": "n8n-nodes-base.webhook",
"parameters": {
"path": "manual-test"
// No error handling - user will retry manually
}
}]
}
```
**Reasoning**: User is present to see and handle errors.
#### When to Fix
**❌ Production Automation**
```javascript
// BAD: Critical workflow without error handling
{
"name": "Process Customer Orders",
"nodes": [{
"type": "n8n-nodes-base.postgres",
"parameters": {
"query": "INSERT INTO orders..."
// ❌ Should have error handling!
}
}]
}
```
**Fix**:
```javascript
{
"parameters": {
"query": "INSERT INTO orders...",
"continueOnFail": true,
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 1000
}
}
```
**❌ Critical Integrations**
```javascript
// BAD: Payment processing without error handling
{
"name": "Process Payment",
"type": "n8n-nodes-base.stripe"
// ❌ Payment failures MUST be handled!
}
```
### 2. No Retry Logic
**Warning**:
```
External API calls should retry on failure
Suggestion: Add retryOnFail: true with exponential backoff
```
#### When Acceptable
**✅ APIs with Built-in Retry**
```javascript
// Stripe has its own retry mechanism
{
"type": "n8n-nodes-base.stripe",
"parameters": {
"resource": "charge",
"operation": "create"
// Stripe SDK retries automatically
}
}
```
**✅ Idempotent Operations**
```javascript
// GET request - safe to retry manually if needed
{
"method": "GET",
"url": "https://api.example.com/status"
// Read-only, no side effects
}
```
**✅ Local/Internal Services**
```javascript
// Internal API with high reliability
{
"url": "http://localhost:3000/process"
// Local service, failures are rare and obvious
}
```
#### When to Fix
**❌ Flaky External APIs**
```javascript
// BAD: Known unreliable API without retries
{
"url": "https://unreliable-api.com/data"
// ❌ Should retry!
}
// GOOD:
{
"url": "https://unreliable-api.com/data",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 2000
}
```
**❌ Non-Idempotent Operations**
```javascript
// BAD: POST without retry - may lose data
{
"method": "POST",
"url": "https://api.example.com/create"
// ❌ Could timeout and lose data
}
```
### 3. Missing Rate Limiting
**Warning**:
```
API may have rate limits
Suggestion: Add rate limiting or batch requests
```
#### When Acceptable
**✅ Internal APIs**
```javascript
// Internal microservice - no rate limits
{
"url": "http://internal-api/process"
// Company controls both ends
}
```
**✅ Low-Volume Workflows**
```javascript
// Runs once per day
{
"trigger": {
"type": "n8n-nodes-base.cron",
"parameters": {
"mode": "everyDay",
"hour": 9
}
},
"nodes": [{
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"url": "https://api.example.com/daily-report"
// Once per day = no rate limit concerns
}
}]
}
```
**✅ APIs with Server-Side Limits**
```javascript
// API returns 429 and n8n handles it
{
"url": "https://api.example.com/data",
"options": {
"response": {
"response": {
"neverError": false // Will error on 429
}
}
},
"retryOnFail": true // Retry on 429
}
```
#### When to Fix
**❌ High-Volume Public APIs**
```javascript
// BAD: Loop hitting rate-limited API
{
"nodes": [{
"type": "n8n-nodes-base.splitInBatches",
"parameters": {
"batchSize": 100
}
}, {
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"url": "https://api.github.com/..."
// ❌ GitHub has strict rate limits!
}
}]
}
// GOOD: Add rate limiting
{
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"url": "https://api.github.com/...",
"options": {
"batching": {
"batch": {
"batchSize": 10,
"batchInterval": 1000 // 1 second between batches
}
}
}
}
}
```
### 4. Unbounded Database Queries
**Warning**:
```
SELECT without LIMIT can return massive datasets
Suggestion: Add LIMIT clause or use pagination
```
#### When Acceptable
**✅ Small Known Datasets**
```javascript
// Config table with ~10 rows
{
"query": "SELECT * FROM app_config"
// Known to be small, no LIMIT needed
}
```
**✅ Aggregation Queries**
```javascript
// COUNT/SUM operations
{
"query": "SELECT COUNT(*) as total FROM users WHERE active = true"
// Aggregation, not returning rows
}
```
**✅ Development/Testing**
```javascript
// Testing with small dataset
{
"query": "SELECT * FROM test_users"
// Test database has 5 rows
}
```
#### When to Fix
**❌ Production Queries on Large Tables**
```javascript
// BAD: User table could have millions of rows
{
"query": "SELECT * FROM users"
// ❌ Could return millions of rows!
}
// GOOD: Add LIMIT
{
"query": "SELECT * FROM users LIMIT 1000"
}
// BETTER: Use pagination
{
"query": "SELECT * FROM users WHERE id > {{$json.lastId}} LIMIT 1000"
}
```
### 5. Missing Input Validation
**Warning**:
```
Webhook doesn't validate input data
Suggestion: Add IF node to validate required fields
```
#### When Acceptable
**✅ Internal Webhooks**
```javascript
// Webhook from your own backend
{
"type": "n8n-nodes-base.webhook",
"parameters": {
"path": "internal-trigger"
// Your backend already validates
}
}
```
**✅ Trusted Sources**
```javascript
// Webhook from Stripe (cryptographically signed)
{
"type": "n8n-nodes-base.webhook",
"parameters": {
"path": "stripe-webhook",
"authentication": "headerAuth"
// Stripe signature validates authenticity
}
}
```
#### When to Fix
**❌ Public Webhooks**
```javascript
// BAD: Public webhook without validation
{
"type": "n8n-nodes-base.webhook",
"parameters": {
"path": "public-form-submit"
// ❌ Anyone can send anything!
}
}
// GOOD: Add validation
{
"nodes": [
{
"name": "Webhook",
"type": "n8n-nodes-base.webhook"
},
{
"name": "Validate Input",
"type": "n8n-nodes-base.if",
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$json.body.email}}",
"operation": "isNotEmpty"
},
{
"value1": "={{$json.body.email}}",
"operation": "regex",
"value2": "^[^@]+@[^@]+\\.[^@]+$"
}
]
}
}
}
]
}
```
### 6. Hardcoded Credentials
**Warning**:
```
Credentials should not be hardcoded
Suggestion: Use n8n credential system
```
#### When Acceptable
**✅ Public APIs (No Auth)**
```javascript
// Truly public API with no secrets
{
"url": "https://api.ipify.org"
// No credentials needed
}
```
**✅ Demo/Example Workflows**
```javascript
// Example workflow in documentation
{
"url": "https://example.com/api",
"headers": {
"Authorization": "Bearer DEMO_TOKEN"
}
// Clearly marked as example
}
```
#### When to Fix (Always!)
**❌ Real Credentials**
```javascript
// BAD: Real API key in workflow
{
"headers": {
"Authorization": "Bearer sk_live_abc123..."
}
// ❌ NEVER hardcode real credentials!
}
// GOOD: Use credentials system
{
"authentication": "headerAuth",
"credentials": {
"headerAuth": {
"id": "credential-id",
"name": "My API Key"
}
}
}
```
## Review Strictness by Workflow Type
**Quick Automations**:
- Review: required fields + expressions
- Accept: Most warnings
- Fix: Only errors + security warnings
**Business-Critical Workflows**:
- Review: full pass (fields, values, types, expressions, connections, error handling, retries, rate limits)
- Accept: Very few warnings
- Fix: Everything possible
**Integration Testing**:
- Review: just enough to execute
- Accept: All warnings (just testing connections)
- Fix: Only errors that prevent execution
## Decision Framework
### Should I Fix This Warning?
```
┌─────────────────────────────────┐
│ Is it a SECURITY warning? │
├─────────────────────────────────┤
│ YES → Always fix │
│ NO → Continue │
└─────────────────────────────────┘
↓
┌─────────────────────────────────┐
│ Is this a production workflow? │
├─────────────────────────────────┤
│ YES → Continue │
│ NO → Probably acceptable │
└─────────────────────────────────┘
↓
┌─────────────────────────────────┐
│ Does it handle critical data? │
├─────────────────────────────────┤
│ YES → Fix the warning │
│ NO → Continue │
└─────────────────────────────────┘
↓
┌─────────────────────────────────┐
│ Is there a known workaround? │
├─────────────────────────────────┤
│ YES → Acceptable if documented │
│ NO → Fix the warning │
└─────────────────────────────────┘
```
## Documentation Template
When accepting a warning, document why (e.g. in a sticky note next to the node, or a comment in the exported JSON):
```javascript
// workflows/customer-notifications.json
{
"nodes": [{
"name": "Send Slack Notification",
"type": "n8n-nodes-base.slack",
"parameters": {
"channel": "#notifications"
// ACCEPTED WARNING: No error handling
// Reason: Non-critical notification, failures are acceptable
// Reviewed: 2025-10-20
// Reviewer: Engineering Team
}
}]
}
```
## Known Structural Quirks
### IF Node Metadata
**Warning**: IF node missing `conditions.options` metadata
**Status**: False positive for IF v2.2+
**Why it occurs**: The editor adds the metadata when the node is saved - JSON written by hand or reviewed before import may lack it
**What to do**: Ignore - metadata is added when the user opens and saves the node
### Switch Branch Count
**Warning**: Switch has 3 rules but 4 output connections
**Status**: False positive when using "fallback" mode
**Why it occurs**: Fallback creates an extra output
**What to do**: Ignore if using fallback intentionally
### Credential Errors Before Execution
**Warning**: Cannot validate credentials without execution context
**Status**: False positive when reviewing static workflow JSON
**Why it occurs**: Credentials are validated at runtime, not build time - exported JSON only carries credential IDs/names
**What to do**: Ignore during review - credentials are checked when the workflow runs on the instance
## Summary
### Always Fix
- ❌ Security warnings
- ❌ Hardcoded credentials
- ❌ SQL injection risks
- ❌ Production workflow errors
### Usually Fix
- ⚠️ Error handling (production)
- ⚠️ Retry logic (external APIs)
- ⚠️ Input validation (public webhooks)
- ⚠️ Rate limiting (high volume)
### Often Acceptable
- ✅ Error handling (dev/test)
- ✅ Retry logic (internal APIs)
- ✅ Rate limiting (low volume)
- ✅ Query limits (small datasets)
### Always Acceptable
- ✅ Community/custom nodes reported as unknown (when installed on the target instance)
- ✅ Intentional polling loops flagged as cycles (with an exit condition)
- ✅ Editor-normalized structures (IF/Switch metadata, operator structure)
- ✅ Static credential checks (validated at runtime)
**Golden Rule**: If you accept a warning, document WHY.
**Related Files**:
- **[SKILL.md](SKILL.md)** - Main guide
- **[ERROR_CATALOG.md](ERROR_CATALOG.md)** - Error types and fixes