@path58/n8n-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/AGENT_INSTALL.md +223 -0
  2. package/CHANGELOG.md +38 -0
  3. package/LICENSE +21 -0
  4. package/README.md +187 -0
  5. package/dist/autofix/suggestion-fixers/deprecated-node-fixer.js +465 -0
  6. package/dist/autofix/suggestion-fixers/deprecated-node-fixer.js.map +1 -0
  7. package/dist/autofix/suggestion-fixers/fixer-registry.js +495 -0
  8. package/dist/autofix/suggestion-fixers/fixer-registry.js.map +1 -0
  9. package/dist/autofix/suggestion-fixers/l1-structure-fixer.js +639 -0
  10. package/dist/autofix/suggestion-fixers/l1-structure-fixer.js.map +1 -0
  11. package/dist/autofix/suggestion-fixers/l4-connection-fixer.js +449 -0
  12. package/dist/autofix/suggestion-fixers/l4-connection-fixer.js.map +1 -0
  13. package/dist/autofix/suggestion-fixers/l5-parameter-fixer.js +575 -0
  14. package/dist/autofix/suggestion-fixers/l5-parameter-fixer.js.map +1 -0
  15. package/dist/autofix/suggestion-fixers/l5-typeversion-fixer.js +431 -0
  16. package/dist/autofix/suggestion-fixers/l5-typeversion-fixer.js.map +1 -0
  17. package/dist/autofix/suggestion-fixers/l5-webhook-path-fixer.js +356 -0
  18. package/dist/autofix/suggestion-fixers/l5-webhook-path-fixer.js.map +1 -0
  19. package/dist/autofix/suggestion-fixers/l6-ai-tool-variant-fixer.js +618 -0
  20. package/dist/autofix/suggestion-fixers/l6-ai-tool-variant-fixer.js.map +1 -0
  21. package/dist/autofix/suggestion-fixers/l6-pattern-fixer.js +1475 -0
  22. package/dist/autofix/suggestion-fixers/l6-pattern-fixer.js.map +1 -0
  23. package/dist/autofix/suggestion-fixers/llm-fixer.js +716 -0
  24. package/dist/autofix/suggestion-fixers/llm-fixer.js.map +1 -0
  25. package/dist/autofix/suggestion-fixers/missing-credential-fixer.js +336 -0
  26. package/dist/autofix/suggestion-fixers/missing-credential-fixer.js.map +1 -0
  27. package/dist/autofix/suggestion-fixers/types.js +29 -0
  28. package/dist/autofix/suggestion-fixers/types.js.map +1 -0
  29. package/dist/autofix/suggestion-fixers/typo-fixer.js +197 -0
  30. package/dist/autofix/suggestion-fixers/typo-fixer.js.map +1 -0
  31. package/dist/classification/certification-engine.js +208 -0
  32. package/dist/classification/certification-engine.js.map +1 -0
  33. package/dist/classification/feedback-collector.js +516 -0
  34. package/dist/classification/feedback-collector.js.map +1 -0
  35. package/dist/classification/l5-parameter-analyzer.js +670 -0
  36. package/dist/classification/l5-parameter-analyzer.js.map +1 -0
  37. package/dist/classification/l6-graph-analyzer.js +613 -0
  38. package/dist/classification/l6-graph-analyzer.js.map +1 -0
  39. package/dist/classification/severity-classifier.js +237 -0
  40. package/dist/classification/severity-classifier.js.map +1 -0
  41. package/dist/config/env.js +280 -0
  42. package/dist/config/env.js.map +1 -0
  43. package/dist/config/env.schema.js +234 -0
  44. package/dist/config/env.schema.js.map +1 -0
  45. package/dist/config/scraperEnv.js +55 -0
  46. package/dist/config/scraperEnv.js.map +1 -0
  47. package/dist/db/postgresClient.js +38 -0
  48. package/dist/db/postgresClient.js.map +1 -0
  49. package/dist/db/scraperDb.js +6 -0
  50. package/dist/db/scraperDb.js.map +1 -0
  51. package/dist/db/scraperPostgresClient.js +118 -0
  52. package/dist/db/scraperPostgresClient.js.map +1 -0
  53. package/dist/db/validationRepository.js +55 -0
  54. package/dist/db/validationRepository.js.map +1 -0
  55. package/dist/db/validatorPostgresClient.js +248 -0
  56. package/dist/db/validatorPostgresClient.js.map +1 -0
  57. package/dist/db/workflowInstanceMappingRepository.js +128 -0
  58. package/dist/db/workflowInstanceMappingRepository.js.map +1 -0
  59. package/dist/errors/AppError.js +156 -0
  60. package/dist/errors/AppError.js.map +1 -0
  61. package/dist/errors/index.js +7 -0
  62. package/dist/errors/index.js.map +1 -0
  63. package/dist/factory/error-to-problem-mappers.js +385 -0
  64. package/dist/factory/error-to-problem-mappers.js.map +1 -0
  65. package/dist/factory/gap-recorder.js +260 -0
  66. package/dist/factory/gap-recorder.js.map +1 -0
  67. package/dist/factory/problem-recorder.js +94 -0
  68. package/dist/factory/problem-recorder.js.map +1 -0
  69. package/dist/factory/warning-to-gap-mappers.js +493 -0
  70. package/dist/factory/warning-to-gap-mappers.js.map +1 -0
  71. package/dist/factory/workflow-normalizer.js +247 -0
  72. package/dist/factory/workflow-normalizer.js.map +1 -0
  73. package/dist/mcp/adapters/catalog.js +13 -0
  74. package/dist/mcp/adapters/catalog.js.map +1 -0
  75. package/dist/mcp/adapters/index.js +36 -0
  76. package/dist/mcp/adapters/index.js.map +1 -0
  77. package/dist/mcp/adapters/supabase-catalog.js +467 -0
  78. package/dist/mcp/adapters/supabase-catalog.js.map +1 -0
  79. package/dist/mcp/adapters/test-catalog-adapter.js +100 -0
  80. package/dist/mcp/adapters/test-catalog-adapter.js.map +1 -0
  81. package/dist/mcp/adapters/validation.js +258 -0
  82. package/dist/mcp/adapters/validation.js.map +1 -0
  83. package/dist/mcp/build-email-workflow.js +113 -0
  84. package/dist/mcp/build-email-workflow.js.map +1 -0
  85. package/dist/mcp/config.js +22 -0
  86. package/dist/mcp/config.js.map +1 -0
  87. package/dist/mcp/formatters/errors.js +217 -0
  88. package/dist/mcp/formatters/errors.js.map +1 -0
  89. package/dist/mcp/formatters/index.js +12 -0
  90. package/dist/mcp/formatters/index.js.map +1 -0
  91. package/dist/mcp/formatters/response.js +141 -0
  92. package/dist/mcp/formatters/response.js.map +1 -0
  93. package/dist/mcp/quick-test.js +33 -0
  94. package/dist/mcp/quick-test.js.map +1 -0
  95. package/dist/mcp/server.js +70 -0
  96. package/dist/mcp/server.js.map +1 -0
  97. package/dist/mcp/test-mcp-error.js +81 -0
  98. package/dist/mcp/test-mcp-error.js.map +1 -0
  99. package/dist/mcp/test-mcp.js +80 -0
  100. package/dist/mcp/test-mcp.js.map +1 -0
  101. package/dist/mcp/tools/fixes/expression-fixes.js +166 -0
  102. package/dist/mcp/tools/fixes/expression-fixes.js.map +1 -0
  103. package/dist/mcp/tools/fixes/flow-fixes.js +155 -0
  104. package/dist/mcp/tools/fixes/flow-fixes.js.map +1 -0
  105. package/dist/mcp/tools/fixes/index.js +91 -0
  106. package/dist/mcp/tools/fixes/index.js.map +1 -0
  107. package/dist/mcp/tools/fixes/node-fixes.js +233 -0
  108. package/dist/mcp/tools/fixes/node-fixes.js.map +1 -0
  109. package/dist/mcp/tools/fixes/parameter-fixes.js +277 -0
  110. package/dist/mcp/tools/fixes/parameter-fixes.js.map +1 -0
  111. package/dist/mcp/tools/fixes/types.js +10 -0
  112. package/dist/mcp/tools/fixes/types.js.map +1 -0
  113. package/dist/mcp/tools/handlers/check-parameter.js +300 -0
  114. package/dist/mcp/tools/handlers/check-parameter.js.map +1 -0
  115. package/dist/mcp/tools/handlers/find-similar-pattern.js +121 -0
  116. package/dist/mcp/tools/handlers/find-similar-pattern.js.map +1 -0
  117. package/dist/mcp/tools/handlers/get-node-info.js +131 -0
  118. package/dist/mcp/tools/handlers/get-node-info.js.map +1 -0
  119. package/dist/mcp/tools/handlers/get-operation-schema.js +141 -0
  120. package/dist/mcp/tools/handlers/get-operation-schema.js.map +1 -0
  121. package/dist/mcp/tools/handlers/list-nodes.js +126 -0
  122. package/dist/mcp/tools/handlers/list-nodes.js.map +1 -0
  123. package/dist/mcp/tools/handlers/list-operations.js +138 -0
  124. package/dist/mcp/tools/handlers/list-operations.js.map +1 -0
  125. package/dist/mcp/tools/handlers/suggest-fix.js +120 -0
  126. package/dist/mcp/tools/handlers/suggest-fix.js.map +1 -0
  127. package/dist/mcp/tools/handlers/validate-workflow.js +92 -0
  128. package/dist/mcp/tools/handlers/validate-workflow.js.map +1 -0
  129. package/dist/mcp/tools/index.js +190 -0
  130. package/dist/mcp/tools/index.js.map +1 -0
  131. package/dist/mcp/tools/schemas.js +195 -0
  132. package/dist/mcp/tools/schemas.js.map +1 -0
  133. package/dist/mcp/tools/validate.js +95 -0
  134. package/dist/mcp/tools/validate.js.map +1 -0
  135. package/dist/mcp/types/mcp.js +7 -0
  136. package/dist/mcp/types/mcp.js.map +1 -0
  137. package/dist/mcp/utils/timeout.js +78 -0
  138. package/dist/mcp/utils/timeout.js.map +1 -0
  139. package/dist/services/BatchProcessor.js +433 -0
  140. package/dist/services/BatchProcessor.js.map +1 -0
  141. package/dist/services/CheckpointManager.js +281 -0
  142. package/dist/services/CheckpointManager.js.map +1 -0
  143. package/dist/services/CostCalculator.js +211 -0
  144. package/dist/services/CostCalculator.js.map +1 -0
  145. package/dist/services/EmbeddingCache.js +68 -0
  146. package/dist/services/EmbeddingCache.js.map +1 -0
  147. package/dist/services/EmbeddingService.js +143 -0
  148. package/dist/services/EmbeddingService.js.map +1 -0
  149. package/dist/services/RankingService.js +81 -0
  150. package/dist/services/RankingService.js.map +1 -0
  151. package/dist/services/RedisCache.js +376 -0
  152. package/dist/services/RedisCache.js.map +1 -0
  153. package/dist/services/RedisCatalogCache.js +680 -0
  154. package/dist/services/RedisCatalogCache.js.map +1 -0
  155. package/dist/services/ResumeManager.js +252 -0
  156. package/dist/services/ResumeManager.js.map +1 -0
  157. package/dist/services/SearchService.js +282 -0
  158. package/dist/services/SearchService.js.map +1 -0
  159. package/dist/services/SemanticCatalogSearch.js +405 -0
  160. package/dist/services/SemanticCatalogSearch.js.map +1 -0
  161. package/dist/services/ValidationCache.js +157 -0
  162. package/dist/services/ValidationCache.js.map +1 -0
  163. package/dist/services/WorkflowPipelineService.js +1997 -0
  164. package/dist/services/WorkflowPipelineService.js.map +1 -0
  165. package/dist/services/catalog/index.js +34 -0
  166. package/dist/services/catalog/index.js.map +1 -0
  167. package/dist/services/catalog/interfaces.js +17 -0
  168. package/dist/services/catalog/interfaces.js.map +1 -0
  169. package/dist/services/catalog/loaders.js +169 -0
  170. package/dist/services/catalog/loaders.js.map +1 -0
  171. package/dist/services/catalog/types.js +138 -0
  172. package/dist/services/catalog/types.js.map +1 -0
  173. package/dist/services/documentation-normalization/docUrlUtils.js +88 -0
  174. package/dist/services/documentation-normalization/docUrlUtils.js.map +1 -0
  175. package/dist/services/error-quality/ErrorQualityService.js +262 -0
  176. package/dist/services/error-quality/ErrorQualityService.js.map +1 -0
  177. package/dist/services/error-quality/analyzers/CredentialAnalyzer.js +260 -0
  178. package/dist/services/error-quality/analyzers/CredentialAnalyzer.js.map +1 -0
  179. package/dist/services/error-quality/analyzers/IssuePredictor.js +380 -0
  180. package/dist/services/error-quality/analyzers/IssuePredictor.js.map +1 -0
  181. package/dist/services/error-quality/analyzers/MockCoverageAnalyzer.js +267 -0
  182. package/dist/services/error-quality/analyzers/MockCoverageAnalyzer.js.map +1 -0
  183. package/dist/services/error-quality/data/ErrorPatternSeeder.js +963 -0
  184. package/dist/services/error-quality/data/ErrorPatternSeeder.js.map +1 -0
  185. package/dist/services/error-quality/index.js +25 -0
  186. package/dist/services/error-quality/index.js.map +1 -0
  187. package/dist/services/error-quality/reports/ReportGenerator.js +343 -0
  188. package/dist/services/error-quality/reports/ReportGenerator.js.map +1 -0
  189. package/dist/services/error-quality/taxonomy/ErrorTaxonomy.js +698 -0
  190. package/dist/services/error-quality/taxonomy/ErrorTaxonomy.js.map +1 -0
  191. package/dist/services/error-quality/types.js +11 -0
  192. package/dist/services/error-quality/types.js.map +1 -0
  193. package/dist/services/progress/ProgressTracker.js +288 -0
  194. package/dist/services/progress/ProgressTracker.js.map +1 -0
  195. package/dist/services/progress/formatters.js +122 -0
  196. package/dist/services/progress/formatters.js.map +1 -0
  197. package/dist/services/progress/index.js +36 -0
  198. package/dist/services/progress/index.js.map +1 -0
  199. package/dist/services/progress/types.js +7 -0
  200. package/dist/services/progress/types.js.map +1 -0
  201. package/dist/services/search/embeddingGenerator.js +112 -0
  202. package/dist/services/search/embeddingGenerator.js.map +1 -0
  203. package/dist/types/aiCapabilities.js +7 -0
  204. package/dist/types/aiCapabilities.js.map +1 -0
  205. package/dist/types/aiConfigSchema.js +7 -0
  206. package/dist/types/aiConfigSchema.js.map +1 -0
  207. package/dist/utils/bannerLogger.js +186 -0
  208. package/dist/utils/bannerLogger.js.map +1 -0
  209. package/dist/utils/bannerService.js +23 -0
  210. package/dist/utils/bannerService.js.map +1 -0
  211. package/dist/utils/bannerServiceAdapter.js +54 -0
  212. package/dist/utils/bannerServiceAdapter.js.map +1 -0
  213. package/dist/utils/batchLogger.js +171 -0
  214. package/dist/utils/batchLogger.js.map +1 -0
  215. package/dist/utils/bottomStickyBanner.js +239 -0
  216. package/dist/utils/bottomStickyBanner.js.map +1 -0
  217. package/dist/utils/credentialMatcher.js +206 -0
  218. package/dist/utils/credentialMatcher.js.map +1 -0
  219. package/dist/utils/credentialNormalizer.js +442 -0
  220. package/dist/utils/credentialNormalizer.js.map +1 -0
  221. package/dist/utils/integratedBannerLogger.js +59 -0
  222. package/dist/utils/integratedBannerLogger.js.map +1 -0
  223. package/dist/utils/n8nSourceGit.js +195 -0
  224. package/dist/utils/n8nSourceGit.js.map +1 -0
  225. package/dist/utils/nodeTypeNormalizer.js +131 -0
  226. package/dist/utils/nodeTypeNormalizer.js.map +1 -0
  227. package/dist/utils/openaiClient.js +397 -0
  228. package/dist/utils/openaiClient.js.map +1 -0
  229. package/dist/utils/productionLogger.js +16 -0
  230. package/dist/utils/productionLogger.js.map +1 -0
  231. package/dist/utils/progressBarBanner.js +132 -0
  232. package/dist/utils/progressBarBanner.js.map +1 -0
  233. package/dist/utils/scriptHeartbeat.js +117 -0
  234. package/dist/utils/scriptHeartbeat.js.map +1 -0
  235. package/dist/utils/scriptLogger.js +125 -0
  236. package/dist/utils/scriptLogger.js.map +1 -0
  237. package/dist/utils/scriptRunner.js +95 -0
  238. package/dist/utils/scriptRunner.js.map +1 -0
  239. package/dist/utils/scriptTimeout.js +128 -0
  240. package/dist/utils/scriptTimeout.js.map +1 -0
  241. package/dist/utils/scriptWrapper.js +219 -0
  242. package/dist/utils/scriptWrapper.js.map +1 -0
  243. package/dist/utils/stickyBanner.js +226 -0
  244. package/dist/utils/stickyBanner.js.map +1 -0
  245. package/dist/utils/terminalSpinner.js +97 -0
  246. package/dist/utils/terminalSpinner.js.map +1 -0
  247. package/dist/utils/threeLineBanner.js +427 -0
  248. package/dist/utils/threeLineBanner.js.map +1 -0
  249. package/dist/utils/validatorCheckpointManager.js +170 -0
  250. package/dist/utils/validatorCheckpointManager.js.map +1 -0
  251. package/dist/utils/validatorConnectionManager.js +124 -0
  252. package/dist/utils/validatorConnectionManager.js.map +1 -0
  253. package/dist/validation/catalog.js +56 -0
  254. package/dist/validation/catalog.js.map +1 -0
  255. package/dist/validation/config/deprecated-nodes.js +234 -0
  256. package/dist/validation/config/deprecated-nodes.js.map +1 -0
  257. package/dist/validation/config/l6-severity.js +227 -0
  258. package/dist/validation/config/l6-severity.js.map +1 -0
  259. package/dist/validation/config/terminal-nodes.js +132 -0
  260. package/dist/validation/config/terminal-nodes.js.map +1 -0
  261. package/dist/validation/config/unreachable-nodes.js +67 -0
  262. package/dist/validation/config/unreachable-nodes.js.map +1 -0
  263. package/dist/validation/core.js +47 -0
  264. package/dist/validation/core.js.map +1 -0
  265. package/dist/validation/docExtraction.js +12 -0
  266. package/dist/validation/docExtraction.js.map +1 -0
  267. package/dist/validation/dryRunMockRunner.js +128 -0
  268. package/dist/validation/dryRunMockRunner.js.map +1 -0
  269. package/dist/validation/fixtureEngine.js +61 -0
  270. package/dist/validation/fixtureEngine.js.map +1 -0
  271. package/dist/validation/index.js +15 -0
  272. package/dist/validation/index.js.map +1 -0
  273. package/dist/validation/k-levels/k2-blockers.js +222 -0
  274. package/dist/validation/k-levels/k2-blockers.js.map +1 -0
  275. package/dist/validation/l1-structure.js +296 -0
  276. package/dist/validation/l1-structure.js.map +1 -0
  277. package/dist/validation/l2-nodes.js +282 -0
  278. package/dist/validation/l2-nodes.js.map +1 -0
  279. package/dist/validation/l3-credentials.js +322 -0
  280. package/dist/validation/l3-credentials.js.map +1 -0
  281. package/dist/validation/l4-connections.js +698 -0
  282. package/dist/validation/l4-connections.js.map +1 -0
  283. package/dist/validation/l5-parameters.js +803 -0
  284. package/dist/validation/l5-parameters.js.map +1 -0
  285. package/dist/validation/l6-checks/ai-tool-variants.js +407 -0
  286. package/dist/validation/l6-checks/ai-tool-variants.js.map +1 -0
  287. package/dist/validation/l6-checks/catalog-checks.js +260 -0
  288. package/dist/validation/l6-checks/catalog-checks.js.map +1 -0
  289. package/dist/validation/l6-checks/data-contracts.js +197 -0
  290. package/dist/validation/l6-checks/data-contracts.js.map +1 -0
  291. package/dist/validation/l6-checks/deprecation.js +133 -0
  292. package/dist/validation/l6-checks/deprecation.js.map +1 -0
  293. package/dist/validation/l6-checks/error-handling.js +193 -0
  294. package/dist/validation/l6-checks/error-handling.js.map +1 -0
  295. package/dist/validation/l6-checks/expression-syntax.js +387 -0
  296. package/dist/validation/l6-checks/expression-syntax.js.map +1 -0
  297. package/dist/validation/l6-checks/flow-integrity.js +504 -0
  298. package/dist/validation/l6-checks/flow-integrity.js.map +1 -0
  299. package/dist/validation/l6-checks/index.js +106 -0
  300. package/dist/validation/l6-checks/index.js.map +1 -0
  301. package/dist/validation/l6-checks/loops.js +370 -0
  302. package/dist/validation/l6-checks/loops.js.map +1 -0
  303. package/dist/validation/l6-checks/performance.js +182 -0
  304. package/dist/validation/l6-checks/performance.js.map +1 -0
  305. package/dist/validation/l6-checks/security.js +273 -0
  306. package/dist/validation/l6-checks/security.js.map +1 -0
  307. package/dist/validation/l6-patterns.js +472 -0
  308. package/dist/validation/l6-patterns.js.map +1 -0
  309. package/dist/validation/mockLevelResolver.js +95 -0
  310. package/dist/validation/mockLevelResolver.js.map +1 -0
  311. package/dist/validation/n8nApiClient.js +21 -0
  312. package/dist/validation/n8nApiClient.js.map +1 -0
  313. package/dist/validation/n8nCli.js +87 -0
  314. package/dist/validation/n8nCli.js.map +1 -0
  315. package/dist/validation/types.js +8 -0
  316. package/dist/validation/types.js.map +1 -0
  317. package/dist/validation/usageStats.js +82 -0
  318. package/dist/validation/usageStats.js.map +1 -0
  319. package/package.json +274 -0
@@ -0,0 +1,193 @@
1
+ /**
2
+ * L6 Error Handling Checks
3
+ *
4
+ * RAG-2.2.40: L6 Pattern Validation
5
+ * Created: January 5, 2026
6
+ *
7
+ * Validates error handling configuration (STRICT MODE):
8
+ * - ERROR_OUTPUT_UNCONNECTED: Error output exists but not connected
9
+ * - NO_RETRY_ON_HTTP: HTTP/API nodes without retry configuration
10
+ *
11
+ * Fix for PM bug #7: Check node-level settings (node.continueOnFail, node.retryOnFail)
12
+ * NOT parameters.continueOnFail
13
+ */
14
+ import { getL6Severity, blocksCertification } from '../config/l6-severity.js';
15
+ /**
16
+ * Check if node has error handling configured
17
+ *
18
+ * n8n error handling settings (at NODE level, not in parameters):
19
+ * - node.continueOnFail: Continue workflow on error
20
+ * - node.retryOnFail: Retry on failure
21
+ * - node.maxTries: Number of retry attempts
22
+ * - node.waitBetweenTries: Delay between retries
23
+ * - node.onError: Error handling behavior
24
+ */
25
+ function hasErrorHandling(node) {
26
+ return (node.continueOnFail === true ||
27
+ node.retryOnFail === true ||
28
+ node.onError !== undefined);
29
+ }
30
+ /**
31
+ * Check if node has retry configuration
32
+ */
33
+ function hasRetryConfig(node) {
34
+ return (node.retryOnFail === true &&
35
+ typeof node.maxTries === 'number' &&
36
+ node.maxTries > 0);
37
+ }
38
+ /**
39
+ * Check 1: ERROR_OUTPUT_UNCONNECTED
40
+ *
41
+ * Nodes with error outputs that aren't connected will silently fail.
42
+ * This is critical for error-prone nodes (HTTP, DB, FTP, Email, etc.)
43
+ *
44
+ * Algorithm:
45
+ * 1. Find all error-prone nodes
46
+ * 2. Check if they have error handling configured
47
+ * 3. If they have error outputs, check if connected
48
+ * 4. If unconnected, flag as error (STRICT MODE)
49
+ */
50
+ export function checkErrorOutputUnconnected(context) {
51
+ const { catalogCache, workflow } = context;
52
+ const errors = [];
53
+ // Guard: malformed workflow JSON (e.g., missing nodes/connections) should not crash L6.
54
+ if (!workflow.nodes || !Array.isArray(workflow.nodes) || !workflow.connections) {
55
+ return errors;
56
+ }
57
+ for (const node of workflow.nodes) {
58
+ // Only check error-prone nodes
59
+ if (!catalogCache.errorProneTypes.has(node.type.toLowerCase())) {
60
+ continue;
61
+ }
62
+ // If node already has error handling configured, skip
63
+ if (hasErrorHandling(node)) {
64
+ continue;
65
+ }
66
+ // Check if error output exists in connections
67
+ const outgoing = workflow.connections[node.name];
68
+ const hasErrorOutput = outgoing && 'error' in outgoing;
69
+ const errorConnected = hasErrorOutput &&
70
+ outgoing.error &&
71
+ outgoing.error.length > 0 &&
72
+ outgoing.error.some(group => group.length > 0);
73
+ // If error output exists but is not connected → ERROR
74
+ if (hasErrorOutput && !errorConnected) {
75
+ const code = 'ERROR_OUTPUT_UNCONNECTED';
76
+ errors.push({
77
+ code: 'ERROR_OUTPUT_UNCONNECTED',
78
+ message: `Node "${node.name}" has an error output but it is not connected. Errors will be silently ignored.`,
79
+ path: `nodes.${node.name}`,
80
+ node_name: node.name,
81
+ node_type: node.type,
82
+ severity: getL6Severity(code),
83
+ blocks_certification: blocksCertification(code),
84
+ suggested_fix: {
85
+ id: `fix-error-output-${node.name}`,
86
+ fix_type: 'connect_error_output',
87
+ confidence: 0.85,
88
+ auto_applicable: false, // Need to know where to connect it
89
+ description: `Connect error output of "${node.name}" to error handler or enable continueOnFail`,
90
+ target_node: node.name,
91
+ patch: {
92
+ // Option 1: Add error handling
93
+ node_settings: {
94
+ continueOnFail: true,
95
+ onError: 'continueRegularOutput',
96
+ },
97
+ // Option 2: Connect error output (requires target)
98
+ new_connection: undefined, // User must specify target
99
+ },
100
+ context: {
101
+ has_error_output: true,
102
+ error_output_connected: false,
103
+ suggestion: 'Either connect error output or enable continueOnFail',
104
+ },
105
+ },
106
+ });
107
+ }
108
+ }
109
+ return errors;
110
+ }
111
+ /**
112
+ * Check 2: NO_RETRY_ON_HTTP
113
+ *
114
+ * HTTP/API nodes without retry configuration are prone to transient failures.
115
+ * Data shows 94.2% of HTTP nodes lack retry config.
116
+ *
117
+ * STRICT MODE: Treat missing retry on HTTP as an ERROR (tests and scoring expect this).
118
+ */
119
+ export function checkNoRetryOnHttp(context) {
120
+ const { catalogCache, workflow } = context;
121
+ const errors = [];
122
+ // Guard: malformed workflow JSON (e.g., missing nodes) should not crash L6.
123
+ if (!workflow.nodes || !Array.isArray(workflow.nodes)) {
124
+ return errors;
125
+ }
126
+ // Common HTTP/API node types
127
+ const httpNodeTypes = new Set([
128
+ 'n8n-nodes-base.httprequest',
129
+ 'n8n-nodes-base.httpRequest', // Alternative casing
130
+ 'httprequest',
131
+ 'httpRequest',
132
+ ]);
133
+ for (const node of workflow.nodes) {
134
+ const nodeTypeLower = node.type.toLowerCase();
135
+ // Check if it's an HTTP node
136
+ const isHttpNode = httpNodeTypes.has(nodeTypeLower) ||
137
+ catalogCache.errorProneTypes.has(nodeTypeLower) && nodeTypeLower.includes('http');
138
+ if (!isHttpNode) {
139
+ continue;
140
+ }
141
+ // Check if retry is configured
142
+ if (hasRetryConfig(node)) {
143
+ continue;
144
+ }
145
+ const code = 'NO_RETRY_ON_HTTP';
146
+ errors.push({
147
+ code: 'NO_RETRY_ON_HTTP',
148
+ message: `HTTP node "${node.name}" has no retry configuration. Consider adding retry for transient failures.`,
149
+ node_name: node.name,
150
+ node_type: node.type,
151
+ severity: getL6Severity(code),
152
+ blocks_certification: blocksCertification(code),
153
+ suggested_fix: {
154
+ id: `fix-no-retry-${node.name}`,
155
+ fix_type: 'add_retry',
156
+ confidence: 0.90, // High confidence - standard retry config
157
+ auto_applicable: true, // Safe to auto-apply standard retry settings
158
+ description: `Add retry configuration to "${node.name}" (3 retries with 1000ms delay)`,
159
+ target_node: node.name,
160
+ patch: {
161
+ node_settings: {
162
+ retryOnFail: true,
163
+ maxTries: 3,
164
+ waitBetweenTries: 1000, // 1 second
165
+ },
166
+ },
167
+ context: {
168
+ reason: 'HTTP nodes should have retry for transient failures',
169
+ recommended_retries: 3,
170
+ recommended_delay_ms: 1000,
171
+ },
172
+ },
173
+ });
174
+ }
175
+ return errors;
176
+ }
177
+ /**
178
+ * Run all error handling checks in parallel
179
+ */
180
+ export async function checkErrorHandling(context) {
181
+ const startTime = performance.now();
182
+ // Run checks in parallel
183
+ const [errorOutputErrors, noRetryErrors,] = await Promise.all([
184
+ Promise.resolve(checkErrorOutputUnconnected(context)),
185
+ Promise.resolve(checkNoRetryOnHttp(context)),
186
+ ]);
187
+ const duration = performance.now() - startTime;
188
+ return {
189
+ errors: [...errorOutputErrors, ...noRetryErrors],
190
+ warnings: [],
191
+ };
192
+ }
193
+ //# sourceMappingURL=error-handling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-handling.js","sourceRoot":"","sources":["../../../src/validation/l6-checks/error-handling.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,387 @@
1
+ /**
2
+ * L6 Expression Syntax Checks
3
+ *
4
+ * RAG-2.2.40: L6 Pattern Validation
5
+ * Created: January 5, 2026
6
+ *
7
+ * Validates n8n expression syntax:
8
+ * - INVALID_EXPRESSION_SYNTAX: Expression cannot be parsed
9
+ * - UNBALANCED_BRACES: {{ }} braces don't match
10
+ *
11
+ * Fix for PM bug #8: Handle nested braces properly
12
+ * Cannot use simple regex [^}]* - need character-by-character parsing
13
+ */
14
+ import { getL6Severity, blocksCertification } from '../config/l6-severity.js';
15
+ /**
16
+ * Extract all expressions from a value (string or nested object)
17
+ */
18
+ function extractExpressions(value, path = '') {
19
+ const expressions = [];
20
+ if (typeof value === 'string') {
21
+ // Find all {{ ... }} patterns
22
+ // Use robust parsing for nested braces
23
+ const matches = findExpressionsInString(value);
24
+ for (const match of matches) {
25
+ expressions.push({ expression: match, path });
26
+ }
27
+ }
28
+ else if (Array.isArray(value)) {
29
+ value.forEach((item, index) => {
30
+ expressions.push(...extractExpressions(item, `${path}[${index}]`));
31
+ });
32
+ }
33
+ else if (value && typeof value === 'object') {
34
+ for (const [key, val] of Object.entries(value)) {
35
+ const newPath = path ? `${path}.${key}` : key;
36
+ expressions.push(...extractExpressions(val, newPath));
37
+ }
38
+ }
39
+ return expressions;
40
+ }
41
+ /**
42
+ * Find all {{ }} expressions in a string, handling nested braces
43
+ *
44
+ * Fix for PM bug #8: Proper nested brace handling
45
+ *
46
+ * Algorithm:
47
+ * 1. Character-by-character scan
48
+ * 2. Track brace depth
49
+ * 3. Extract when depth returns to 0
50
+ *
51
+ * Example: "{{ $json.items.filter(x => { return x.active; }) }}"
52
+ * Should extract the entire expression, not stop at first }
53
+ */
54
+ function findExpressionsInString(str) {
55
+ const expressions = [];
56
+ let i = 0;
57
+ while (i < str.length - 1) {
58
+ // Look for opening {{
59
+ if (str[i] === '{' && str[i + 1] === '{') {
60
+ const startIndex = i;
61
+ i += 2; // Skip past {{
62
+ let depth = 1; // Start at depth 1 (we've seen {{)
63
+ let braceCount = 0; // Track inner {} pairs
64
+ // Scan until we find matching }}
65
+ while (i < str.length - 1 && depth > 0) {
66
+ if (str[i] === '{' && str[i + 1] === '{') {
67
+ depth++;
68
+ i += 2;
69
+ }
70
+ else if (str[i] === '}' && str[i + 1] === '}') {
71
+ depth--;
72
+ i += 2;
73
+ if (depth === 0) {
74
+ // Found matching }}
75
+ const expression = str.substring(startIndex, i);
76
+ expressions.push(expression);
77
+ }
78
+ }
79
+ else if (str[i] === '{') {
80
+ braceCount++;
81
+ i++;
82
+ }
83
+ else if (str[i] === '}') {
84
+ braceCount--;
85
+ i++;
86
+ }
87
+ else {
88
+ i++;
89
+ }
90
+ }
91
+ // If we exited loop without depth === 0, expression is unbalanced
92
+ if (depth > 0) {
93
+ expressions.push(str.substring(startIndex)); // Include unbalanced expression for error reporting
94
+ }
95
+ }
96
+ else {
97
+ i++;
98
+ }
99
+ }
100
+ return expressions;
101
+ }
102
+ /**
103
+ * Check if expression has balanced {{ }} pairs
104
+ */
105
+ function hasBalancedBraces(expression) {
106
+ let outerDepth = 0; // Track {{ }} depth
107
+ let innerDepth = 0; // Track { } depth inside expression
108
+ let i = 0;
109
+ while (i < expression.length - 1) {
110
+ if (expression[i] === '{' && expression[i + 1] === '{') {
111
+ outerDepth++;
112
+ i += 2;
113
+ }
114
+ else if (expression[i] === '}' && expression[i + 1] === '}') {
115
+ outerDepth--;
116
+ i += 2;
117
+ }
118
+ else if (expression[i] === '{') {
119
+ innerDepth++;
120
+ i++;
121
+ }
122
+ else if (expression[i] === '}') {
123
+ innerDepth--;
124
+ i++;
125
+ }
126
+ else {
127
+ i++;
128
+ }
129
+ }
130
+ return outerDepth === 0 && innerDepth === 0;
131
+ }
132
+ /**
133
+ * Validate expression syntax (basic checks)
134
+ *
135
+ * Full expression validation would require parsing JavaScript,
136
+ * but we can catch common syntax errors:
137
+ * - Unmatched quotes (accounting for escapes and nesting)
138
+ * - Incomplete ternary operators
139
+ * - Missing closing parentheses (accounting for string contexts)
140
+ *
141
+ * RAG-2.2.108.5: Fixed false positives by properly handling:
142
+ * - Escaped quotes: \' and \"
143
+ * - Quotes inside different quote types: "it's" or 'say "hi"'
144
+ * - Parentheses inside strings: .replaceAll(')', '')
145
+ * - Parentheses inside regex: /(?=\(pattern)/
146
+ */
147
+ function validateExpressionSyntax(expression) {
148
+ // Remove {{ }} wrapper
149
+ const inner = expression.replace(/^\{\{/, '').replace(/\}\}$/, '').trim();
150
+ // State machine to track string/regex context
151
+ let inSingleQuote = false;
152
+ let inDoubleQuote = false;
153
+ let inBacktick = false;
154
+ let inRegex = false;
155
+ let parenDepth = 0;
156
+ for (let i = 0; i < inner.length; i++) {
157
+ const char = inner[i];
158
+ const prevChar = i > 0 ? inner[i - 1] : '';
159
+ const nextChar = i < inner.length - 1 ? inner[i + 1] : '';
160
+ // Skip escaped characters
161
+ if (prevChar === '\\') {
162
+ continue;
163
+ }
164
+ // Handle string contexts
165
+ if (char === "'" && !inDoubleQuote && !inBacktick && !inRegex) {
166
+ inSingleQuote = !inSingleQuote;
167
+ continue;
168
+ }
169
+ if (char === '"' && !inSingleQuote && !inBacktick && !inRegex) {
170
+ inDoubleQuote = !inDoubleQuote;
171
+ continue;
172
+ }
173
+ if (char === '`' && !inSingleQuote && !inDoubleQuote && !inRegex) {
174
+ inBacktick = !inBacktick;
175
+ continue;
176
+ }
177
+ // Handle regex context (simplified: /.../ not preceded by division context)
178
+ // This is a heuristic - true regex detection requires full parsing
179
+ if (char === '/' && !inSingleQuote && !inDoubleQuote && !inBacktick) {
180
+ // Check if this could be start of regex (not division)
181
+ // Regex typically follows: (, [, {, ,, =, :, ;, !, &, |, ?, or start
182
+ if (!inRegex) {
183
+ const regexPrecursors = /[([\]{},=:;!&|?+\-*\n\r\t ]/;
184
+ if (i === 0 || regexPrecursors.test(prevChar)) {
185
+ inRegex = true;
186
+ continue;
187
+ }
188
+ }
189
+ else {
190
+ // End of regex
191
+ inRegex = false;
192
+ continue;
193
+ }
194
+ }
195
+ // Only count parentheses outside of strings and regex
196
+ if (!inSingleQuote && !inDoubleQuote && !inBacktick && !inRegex) {
197
+ if (char === '(')
198
+ parenDepth++;
199
+ if (char === ')')
200
+ parenDepth--;
201
+ if (parenDepth < 0) {
202
+ return { valid: false, reason: 'Unmatched closing parenthesis' };
203
+ }
204
+ }
205
+ }
206
+ // Check for unclosed strings
207
+ if (inSingleQuote) {
208
+ return { valid: false, reason: 'Unmatched single quote' };
209
+ }
210
+ if (inDoubleQuote) {
211
+ return { valid: false, reason: 'Unmatched double quote' };
212
+ }
213
+ if (inBacktick) {
214
+ return { valid: false, reason: 'Unmatched backtick' };
215
+ }
216
+ // Check for unmatched parentheses
217
+ if (parenDepth !== 0) {
218
+ return { valid: false, reason: 'Unmatched opening parenthesis' };
219
+ }
220
+ return { valid: true };
221
+ }
222
+ /**
223
+ * Check 1: UNBALANCED_BRACES
224
+ * Detect {{ }} expressions with mismatched braces
225
+ */
226
+ export function checkUnbalancedBraces(context) {
227
+ const { workflow } = context;
228
+ const errors = [];
229
+ for (const node of workflow.nodes) {
230
+ const expressions = extractExpressions(node.parameters, `nodes.${node.name}.parameters`);
231
+ for (const { expression, path } of expressions) {
232
+ if (!hasBalancedBraces(expression)) {
233
+ const code = 'UNBALANCED_BRACES';
234
+ errors.push({
235
+ code: 'UNBALANCED_BRACES',
236
+ message: `Expression has unbalanced {{ }} braces: "${expression.substring(0, 50)}..."`,
237
+ path,
238
+ node_name: node.name,
239
+ node_type: node.type,
240
+ severity: getL6Severity(code),
241
+ blocks_certification: blocksCertification(code),
242
+ suggested_fix: {
243
+ id: `fix-unbalanced-${node.name}-${path}`,
244
+ fix_type: 'fix_expression',
245
+ confidence: 0.60, // Medium confidence - hard to auto-fix without knowing intent
246
+ auto_applicable: false,
247
+ description: `Fix brace balancing in expression at ${path}`,
248
+ target_node: node.name,
249
+ patch: {
250
+ expression_fix: {
251
+ old_value: expression,
252
+ new_value: expression, // Cannot auto-fix without understanding intent
253
+ field_path: path,
254
+ },
255
+ },
256
+ context: {
257
+ reason: 'Unbalanced {{ }} braces',
258
+ expression_preview: expression.substring(0, 100),
259
+ },
260
+ },
261
+ });
262
+ }
263
+ }
264
+ }
265
+ return errors;
266
+ }
267
+ /**
268
+ * Check 2: INVALID_EXPRESSION_SYNTAX
269
+ * Detect expressions with basic syntax errors
270
+ */
271
+ export function checkInvalidExpressionSyntax(context) {
272
+ const { workflow } = context;
273
+ const errors = [];
274
+ for (const node of workflow.nodes) {
275
+ const expressions = extractExpressions(node.parameters, `nodes.${node.name}.parameters`);
276
+ for (const { expression, path } of expressions) {
277
+ const validation = validateExpressionSyntax(expression);
278
+ if (!validation.valid) {
279
+ const code = 'INVALID_EXPRESSION_SYNTAX';
280
+ errors.push({
281
+ code: 'INVALID_EXPRESSION_SYNTAX',
282
+ message: `Expression has syntax error: ${validation.reason}`,
283
+ path,
284
+ node_name: node.name,
285
+ node_type: node.type,
286
+ severity: getL6Severity(code),
287
+ blocks_certification: blocksCertification(code),
288
+ details: {
289
+ expression_preview: expression.substring(0, 100),
290
+ error_reason: validation.reason,
291
+ },
292
+ suggested_fix: {
293
+ id: `fix-syntax-${node.name}-${path}`,
294
+ fix_type: 'fix_expression',
295
+ confidence: 0.95, // High confidence for quote/paren fixes
296
+ auto_applicable: !!(validation.reason?.includes('quote') || validation.reason?.includes('parenthesis')),
297
+ description: `Fix ${validation.reason} in expression`,
298
+ target_node: node.name,
299
+ patch: {
300
+ expression_fix: {
301
+ old_value: expression,
302
+ new_value: expression, // Auto-fix would add missing quote/paren
303
+ field_path: path,
304
+ },
305
+ },
306
+ context: {
307
+ syntax_error: validation.reason,
308
+ expression_preview: expression.substring(0, 100),
309
+ },
310
+ },
311
+ });
312
+ }
313
+ }
314
+ }
315
+ return errors;
316
+ }
317
+ /**
318
+ * Check 3: EMPTY_EXPRESSION
319
+ * Detect expressions that contain only whitespace: {{ }} or {{ }}
320
+ *
321
+ * RAG-2.2.77: New pattern check
322
+ */
323
+ export function checkEmptyExpressions(context) {
324
+ const { workflow } = context;
325
+ const warnings = [];
326
+ // Guard: Ensure workflow.nodes exists
327
+ if (!workflow.nodes || !Array.isArray(workflow.nodes)) {
328
+ return warnings;
329
+ }
330
+ // Pattern to match empty expressions: {{ }} with any whitespace
331
+ const emptyExprPattern = /\{\{\s*\}\}/g;
332
+ for (const node of workflow.nodes) {
333
+ const params = JSON.stringify(node.parameters || {});
334
+ const matches = params.match(emptyExprPattern);
335
+ if (matches && matches.length > 0) {
336
+ const code = 'EMPTY_EXPRESSION';
337
+ warnings.push({
338
+ code: 'EMPTY_EXPRESSION',
339
+ message: `Node "${node.name}" contains ${matches.length} empty expression(s) "{{ }}" - likely unintentional`,
340
+ node_name: node.name,
341
+ node_type: node.type,
342
+ severity: getL6Severity(code),
343
+ blocks_certification: blocksCertification(code),
344
+ details: {
345
+ empty_count: matches.length,
346
+ },
347
+ suggested_fix: {
348
+ id: `fix-empty-expr-${node.name}-${Date.now()}`,
349
+ fix_type: 'remove_expression',
350
+ confidence: 0.7,
351
+ auto_applicable: false,
352
+ description: 'Remove empty expressions or add meaningful content',
353
+ target_node: node.name,
354
+ patch: {},
355
+ context: {
356
+ empty_expression_count: matches.length,
357
+ },
358
+ },
359
+ });
360
+ }
361
+ }
362
+ return warnings;
363
+ }
364
+ /**
365
+ * Run all expression syntax checks in parallel
366
+ *
367
+ * RAG-2.2.77: Added EMPTY_EXPRESSION check
368
+ */
369
+ export async function checkExpressionSyntax(context) {
370
+ const startTime = performance.now();
371
+ // Run checks in parallel
372
+ // RAG-2.2.77: Added emptyExpressionWarnings
373
+ const [unbalancedErrors, syntaxErrors, emptyExpressionWarnings,] = await Promise.all([
374
+ Promise.resolve(checkUnbalancedBraces(context)),
375
+ Promise.resolve(checkInvalidExpressionSyntax(context)),
376
+ Promise.resolve(checkEmptyExpressions(context)),
377
+ ]);
378
+ const duration = performance.now() - startTime;
379
+ return {
380
+ errors: [
381
+ ...unbalancedErrors,
382
+ ...syntaxErrors,
383
+ ],
384
+ warnings: emptyExpressionWarnings,
385
+ };
386
+ }
387
+ //# sourceMappingURL=expression-syntax.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expression-syntax.js","sourceRoot":"","sources":["../../../src/validation/l6-checks/expression-syntax.ts"],"names":[],"mappings":"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"}