valn8n 0.1.0__tar.gz

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 (144) hide show
  1. valn8n-0.1.0/.gitignore +71 -0
  2. valn8n-0.1.0/.mypy.ini +15 -0
  3. valn8n-0.1.0/.pre-commit-config.yaml +10 -0
  4. valn8n-0.1.0/.pylintrc +14 -0
  5. valn8n-0.1.0/.vscode/extensions.json +11 -0
  6. valn8n-0.1.0/.vscode/settings.json +45 -0
  7. valn8n-0.1.0/LICENSE +21 -0
  8. valn8n-0.1.0/PKG-INFO +167 -0
  9. valn8n-0.1.0/README.md +147 -0
  10. valn8n-0.1.0/demo_valn8n/broken_vs_notbroken/README.md +17 -0
  11. valn8n-0.1.0/demo_valn8n/broken_vs_notbroken/broken_1521_Whatsapp_Stickynote_Automation_Webhook.json +471 -0
  12. valn8n-0.1.0/demo_valn8n/broken_vs_notbroken/lessbroken_3859-ai-customer-support-assistant-whatsapp-ready-works-for-any-business.json +395 -0
  13. valn8n-0.1.0/pyproject.toml +44 -0
  14. valn8n-0.1.0/pytest.ini +3 -0
  15. valn8n-0.1.0/ruff.toml +107 -0
  16. valn8n-0.1.0/src/valn8n/__init__.py +14 -0
  17. valn8n-0.1.0/src/valn8n/cli/__init__.py +13 -0
  18. valn8n-0.1.0/src/valn8n/cli/args.py +85 -0
  19. valn8n-0.1.0/src/valn8n/cli/commands.py +154 -0
  20. valn8n-0.1.0/src/valn8n/entry.py +10 -0
  21. valn8n-0.1.0/src/valn8n_lib/__init__.py +29 -0
  22. valn8n-0.1.0/src/valn8n_lib/data/__init__.py +1 -0
  23. valn8n-0.1.0/src/valn8n_lib/data/common_mistakes.json +18 -0
  24. valn8n-0.1.0/src/valn8n_lib/data/credential_index.json +14803 -0
  25. valn8n-0.1.0/src/valn8n_lib/data/filter_operators.json +76 -0
  26. valn8n-0.1.0/src/valn8n_lib/data/node_categories.md +572 -0
  27. valn8n-0.1.0/src/valn8n_lib/data/node_index.json +52517 -0
  28. valn8n-0.1.0/src/valn8n_lib/data/node_keys.json +169 -0
  29. valn8n-0.1.0/src/valn8n_lib/data/parameter_schemas.json +119 -0
  30. valn8n-0.1.0/src/valn8n_lib/output/__init__.py +21 -0
  31. valn8n-0.1.0/src/valn8n_lib/output/formatters.py +204 -0
  32. valn8n-0.1.0/src/valn8n_lib/output/output.py +15 -0
  33. valn8n-0.1.0/src/valn8n_lib/output/protocol.py +21 -0
  34. valn8n-0.1.0/src/valn8n_lib/rules/CLAUDE.md +31 -0
  35. valn8n-0.1.0/src/valn8n_lib/rules/__init__.py +45 -0
  36. valn8n-0.1.0/src/valn8n_lib/rules/_catalog.py +83 -0
  37. valn8n-0.1.0/src/valn8n_lib/rules/_nd_filter_common.py +45 -0
  38. valn8n-0.1.0/src/valn8n_lib/rules/io_0001.py +6 -0
  39. valn8n-0.1.0/src/valn8n_lib/rules/io_0002.py +6 -0
  40. valn8n-0.1.0/src/valn8n_lib/rules/io_0010.py +6 -0
  41. valn8n-0.1.0/src/valn8n_lib/rules/nd_0101.py +60 -0
  42. valn8n-0.1.0/src/valn8n_lib/rules/nd_0102.py +53 -0
  43. valn8n-0.1.0/src/valn8n_lib/rules/nd_0201.py +54 -0
  44. valn8n-0.1.0/src/valn8n_lib/rules/nd_0202.py +114 -0
  45. valn8n-0.1.0/src/valn8n_lib/rules/nd_0203.py +82 -0
  46. valn8n-0.1.0/src/valn8n_lib/rules/nd_0301.py +324 -0
  47. valn8n-0.1.0/src/valn8n_lib/rules/nd_0302.py +145 -0
  48. valn8n-0.1.0/src/valn8n_lib/rules/nd_0401.py +95 -0
  49. valn8n-0.1.0/src/valn8n_lib/rules/nd_0402.py +72 -0
  50. valn8n-0.1.0/src/valn8n_lib/rules/nd_0501.py +59 -0
  51. valn8n-0.1.0/src/valn8n_lib/rules/nd_0502.py +49 -0
  52. valn8n-0.1.0/src/valn8n_lib/rules/nd_0503.py +52 -0
  53. valn8n-0.1.0/src/valn8n_lib/rules/nd_0504.py +58 -0
  54. valn8n-0.1.0/src/valn8n_lib/rules/nd_0601.py +100 -0
  55. valn8n-0.1.0/src/valn8n_lib/rules/nd_0602.py +69 -0
  56. valn8n-0.1.0/src/valn8n_lib/rules/nd_0603.py +146 -0
  57. valn8n-0.1.0/src/valn8n_lib/rules/nd_0701.py +44 -0
  58. valn8n-0.1.0/src/valn8n_lib/rules/nd_0702.py +94 -0
  59. valn8n-0.1.0/src/valn8n_lib/rules/nd_0801.py +66 -0
  60. valn8n-0.1.0/src/valn8n_lib/rules/nd_0802.py +67 -0
  61. valn8n-0.1.0/src/valn8n_lib/rules/nd_0803.py +41 -0
  62. valn8n-0.1.0/src/valn8n_lib/rules/registry.py +88 -0
  63. valn8n-0.1.0/src/valn8n_lib/source_map.py +39 -0
  64. valn8n-0.1.0/src/valn8n_lib/types.py +99 -0
  65. valn8n-0.1.0/src/valn8n_lib/validator.py +116 -0
  66. valn8n-0.1.0/tests/fixtures/__init__.py +10 -0
  67. valn8n-0.1.0/tests/fixtures/test_cli/gna.json +1 -0
  68. valn8n-0.1.0/tests/fixtures/workflows/test_broken_n8nexpression/broken1.json +65 -0
  69. valn8n-0.1.0/tests/fixtures/workflows/test_broken_n8nexpression/broken1.lst +1 -0
  70. valn8n-0.1.0/tests/fixtures/workflows/test_brokenzie619/1521_Whatsapp_Stickynote_Automation_Webhook.json +471 -0
  71. valn8n-0.1.0/tests/fixtures/workflows/test_brokenzie619/3859-ai-customer-support-assistant-whatsapp-ready-works-for-any-business.json +395 -0
  72. valn8n-0.1.0/tests/fixtures/workflows/test_connections/ai_subnodes.json +20 -0
  73. valn8n-0.1.0/tests/fixtures/workflows/test_connections/ai_subnodes.lst +1 -0
  74. valn8n-0.1.0/tests/fixtures/workflows/test_connections/clean_workflow.json +13 -0
  75. valn8n-0.1.0/tests/fixtures/workflows/test_connections/clean_workflow.lst +1 -0
  76. valn8n-0.1.0/tests/fixtures/workflows/test_connections/dangling_connection.json +15 -0
  77. valn8n-0.1.0/tests/fixtures/workflows/test_connections/dangling_connection.lst +2 -0
  78. valn8n-0.1.0/tests/fixtures/workflows/test_connections/disabled_unconnected.json +8 -0
  79. valn8n-0.1.0/tests/fixtures/workflows/test_connections/disabled_unconnected.lst +1 -0
  80. valn8n-0.1.0/tests/fixtures/workflows/test_connections/invalid_connection_index.json +12 -0
  81. valn8n-0.1.0/tests/fixtures/workflows/test_connections/invalid_connection_index.lst +1 -0
  82. valn8n-0.1.0/tests/fixtures/workflows/test_connections/invalid_connection_type.json +12 -0
  83. valn8n-0.1.0/tests/fixtures/workflows/test_connections/invalid_connection_type.lst +1 -0
  84. valn8n-0.1.0/tests/fixtures/workflows/test_connections/unconnected_node.json +13 -0
  85. valn8n-0.1.0/tests/fixtures/workflows/test_connections/unconnected_node.lst +1 -0
  86. valn8n-0.1.0/tests/fixtures/workflows/test_credentials/empty_cred_id.json +18 -0
  87. valn8n-0.1.0/tests/fixtures/workflows/test_credentials/empty_cred_id.lst +4 -0
  88. valn8n-0.1.0/tests/fixtures/workflows/test_credentials/leaking_cred.json +18 -0
  89. valn8n-0.1.0/tests/fixtures/workflows/test_credentials/leaking_cred.lst +4 -0
  90. valn8n-0.1.0/tests/fixtures/workflows/test_credentials/missing_creds.json +13 -0
  91. valn8n-0.1.0/tests/fixtures/workflows/test_credentials/missing_creds.lst +4 -0
  92. valn8n-0.1.0/tests/fixtures/workflows/test_credentials/placeholder_cred_id.json +18 -0
  93. valn8n-0.1.0/tests/fixtures/workflows/test_credentials/placeholder_cred_id.lst +4 -0
  94. valn8n-0.1.0/tests/fixtures/workflows/test_deep_params/collection_typo.json +17 -0
  95. valn8n-0.1.0/tests/fixtures/workflows/test_deep_params/collection_typo.lst +1 -0
  96. valn8n-0.1.0/tests/fixtures/workflows/test_deep_params/filter_typo.json +34 -0
  97. valn8n-0.1.0/tests/fixtures/workflows/test_deep_params/filter_typo.lst +1 -0
  98. valn8n-0.1.0/tests/fixtures/workflows/test_deep_params/valid_filter.json +37 -0
  99. valn8n-0.1.0/tests/fixtures/workflows/test_deep_params/valid_filter.lst +1 -0
  100. valn8n-0.1.0/tests/fixtures/workflows/test_fil/invalid_op_common.json +125 -0
  101. valn8n-0.1.0/tests/fixtures/workflows/test_fil/invalid_op_common.lst +4 -0
  102. valn8n-0.1.0/tests/fixtures/workflows/test_fil/invalid_op_other.json +125 -0
  103. valn8n-0.1.0/tests/fixtures/workflows/test_fil/invalid_op_other.lst +4 -0
  104. valn8n-0.1.0/tests/fixtures/workflows/test_io/README.txt +1 -0
  105. valn8n-0.1.0/tests/fixtures/workflows/test_io/addcomma.json +11 -0
  106. valn8n-0.1.0/tests/fixtures/workflows/test_io/addcomma.lst +1 -0
  107. valn8n-0.1.0/tests/fixtures/workflows/test_io/nocomma.json +11 -0
  108. valn8n-0.1.0/tests/fixtures/workflows/test_io/nocomma.lst +1 -0
  109. valn8n-0.1.0/tests/fixtures/workflows/test_io/zero.json +0 -0
  110. valn8n-0.1.0/tests/fixtures/workflows/test_io/zero.lst +1 -0
  111. valn8n-0.1.0/tests/fixtures/workflows/test_other/color_node.json +13 -0
  112. valn8n-0.1.0/tests/fixtures/workflows/test_other/color_node.lst +3 -0
  113. valn8n-0.1.0/tests/fixtures/workflows/test_other/invalid_key.json +11 -0
  114. valn8n-0.1.0/tests/fixtures/workflows/test_other/invalid_key.lst +4 -0
  115. valn8n-0.1.0/tests/fixtures/workflows/test_other/invalid_key2.json +125 -0
  116. valn8n-0.1.0/tests/fixtures/workflows/test_other/invalid_key2.lst +4 -0
  117. valn8n-0.1.0/tests/fixtures/workflows/test_suspect_expression/suspect1.json +28 -0
  118. valn8n-0.1.0/tests/fixtures/workflows/test_suspect_expression/suspect1.lst +1 -0
  119. valn8n-0.1.0/tests/fixtures/workflows/test_tolerate_node_keys/0302_Manual_N8Ntrainingcustomerdatastore_Automate_Triggered.json +106 -0
  120. valn8n-0.1.0/tests/fixtures/workflows/test_tolerate_node_keys/0645_Splitout_Code_Sync_Webhook.json +720 -0
  121. valn8n-0.1.0/tests/fixtures/workflows/test_wrongvaltype/wrong_param_type.json +20 -0
  122. valn8n-0.1.0/tests/fixtures/workflows/test_wrongvaltype/wrong_param_type.lst +5 -0
  123. valn8n-0.1.0/tests/fixtures/workflows/test_wrongvaltype/wrong_typeversion.json +12 -0
  124. valn8n-0.1.0/tests/fixtures/workflows/test_wrongvaltype/wrong_typeversion.lst +4 -0
  125. valn8n-0.1.0/tests/fixtures/workflows/test_wrongvaltype/wrongpos.json +16 -0
  126. valn8n-0.1.0/tests/fixtures/workflows/test_wrongvaltype/wrongpos.lst +4 -0
  127. valn8n-0.1.0/tests/rulesets/__init__.py +0 -0
  128. valn8n-0.1.0/tests/rulesets/test_broken_expr.py +168 -0
  129. valn8n-0.1.0/tests/rulesets/test_connections.py +59 -0
  130. valn8n-0.1.0/tests/rulesets/test_credentials.py +28 -0
  131. valn8n-0.1.0/tests/rulesets/test_deep_params.py +161 -0
  132. valn8n-0.1.0/tests/rulesets/test_error_handling.py +222 -0
  133. valn8n-0.1.0/tests/rulesets/test_fil.py +51 -0
  134. valn8n-0.1.0/tests/rulesets/test_io.py +28 -0
  135. valn8n-0.1.0/tests/rulesets/test_naming_docs.py +247 -0
  136. valn8n-0.1.0/tests/rulesets/test_other.py +108 -0
  137. valn8n-0.1.0/tests/rulesets/test_param_keys.py +166 -0
  138. valn8n-0.1.0/tests/rulesets/test_suspect_expr.py +125 -0
  139. valn8n-0.1.0/tests/rulesets/test_val_types.py +749 -0
  140. valn8n-0.1.0/tests/test_cli.py +513 -0
  141. valn8n-0.1.0/tests/test_source_map.py +63 -0
  142. valn8n-0.1.0/tests/test_suggestions.py +56 -0
  143. valn8n-0.1.0/uv.lock +458 -0
  144. valn8n-0.1.0/valn8n +7 -0
@@ -0,0 +1,71 @@
1
+ # From https://github.com/ArjanCodes/examples/blob/main/2024/vscode_python/.gitignore
2
+
3
+ # Byte-compiled / optimized / DLL files
4
+ __pycache__/
5
+ *.py[cod]
6
+ *$py.class
7
+
8
+ # C extensions
9
+ *.so
10
+
11
+ # Distribution / packaging
12
+ .Python
13
+ build/
14
+ develop-eggs/
15
+ dist/
16
+ downloads/
17
+ eggs/
18
+ .eggs/
19
+ lib/
20
+ lib64/
21
+ parts/
22
+ sdist/
23
+ var/
24
+ wheels/
25
+ pip-wheel-metadata/
26
+ share/python-wheels/
27
+ *.egg-info/
28
+ .installed.cfg
29
+ *.egg
30
+ MANIFEST
31
+
32
+ # Virtual environment directories
33
+ env/
34
+ venv/
35
+ ENV/
36
+ env.bak/
37
+ venv.bak
38
+ .venv/
39
+
40
+
41
+ # Unit test / coverage reports
42
+ htmlcov/
43
+ .tox/
44
+ .nox/
45
+ .coverage
46
+ .coverage.*
47
+ .cache
48
+ nosetests.xml
49
+ coverage.xml
50
+ *.cover
51
+ *.py,cover
52
+ .hypothesis
53
+ .pytest_cache
54
+ cover
55
+
56
+ # Jupyter Notebook
57
+ .ipynb_checkpoints
58
+
59
+ # python version
60
+ .python-version
61
+
62
+ # Various tool caches (BaCh)
63
+ .ruff_cache
64
+ .mypy_cache
65
+
66
+ # Various backup files (BaCh)
67
+ *~
68
+ *.bak
69
+
70
+ # This project
71
+ n8n-src/
valn8n-0.1.0/.mypy.ini ADDED
@@ -0,0 +1,15 @@
1
+ [mypy]
2
+ exclude = .venv/
3
+ #plugins = pydantic.mypy
4
+ disallow_untyped_defs = True
5
+ disallow_any_unimported = True
6
+ no_implicit_optional = True
7
+ check_untyped_defs = True
8
+ warn_return_any = True
9
+ show_error_codes = True
10
+ warn_unused_ignores = True
11
+
12
+ [pydantic-mypy]
13
+ init_forbid_extra = True
14
+ init_typed = True
15
+ #warn_required_dynamic_aliases = True
@@ -0,0 +1,10 @@
1
+ repos:
2
+ - repo: local
3
+ hooks:
4
+ - id: validate-commit-message
5
+ name: Validate Commit Message
6
+ language: python
7
+ entry: python devsupport/check_commitmsg.py
8
+ always_run: false
9
+ pass_filenames: true
10
+ stages: [commit-msg]
valn8n-0.1.0/.pylintrc ADDED
@@ -0,0 +1,14 @@
1
+ [FORMAT]
2
+ max-line-length=100
3
+
4
+ [MESSAGES CONTROL]
5
+ # Quieten pylint messages that are duplicate of other tools (ruff, pyright)
6
+ # or where the rules get in each others way.
7
+ disable=
8
+ R0912, # Duplicate of ruff PLR...
9
+ R0913, # Duplicate of ruff PLR...
10
+ R0915, # Duplicate of ruff PLR...
11
+ R1711, # Duplicate of ruff PLR...
12
+ unnecessary-ellipsis, # makes pyright complain e.g. for protocol classes with return type
13
+ too-few-public-methods, # not useful for protocol/dataclass-heavy code
14
+ wrong-import-position # wrong-import-position - duplicate of Ruff E402. And pylint has different oppinion
@@ -0,0 +1,11 @@
1
+ {
2
+ "recommendations": [
3
+ "ms-python.python",
4
+ "ms-python.vscode-pylance",
5
+ "charliermarsh.ruff",
6
+ "tamasfe.even-better-toml",
7
+ "aaron-bond.better-comments",
8
+ "github.vscode-github-actions",
9
+ "bierner.markdown-mermaid",
10
+ ]
11
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ // // Python settings
3
+ // "python.analysis.autoSearchPaths": true,
4
+ // These are driving me nuts when using PyTorch, and as pyright has no way to switch
5
+ // them off on a file by file basis ... screw it, and trust mypy
6
+ "python.analysis.diagnosticSeverityOverrides": {
7
+ "reportMissingTypeArgument": "none",
8
+ "reportUnknownArgumentType": "none",
9
+ "reportUnknownMemberType": "none",
10
+ "reportUnknownParameterType": "none",
11
+ "reportUnknownVariableType": "none",
12
+ },
13
+ // "python.analysis.extraPaths": [
14
+ // "${workspaceFolder}/src"
15
+ // ],
16
+ // "python.envFile": "${workspaceFolder}/.env",
17
+ // "python.terminal.activateEnvironment": true,
18
+ // // Test settings
19
+ // "python.testing.pytestEnabled": true,
20
+ // "python.testing.unittestEnabled": false,
21
+ // "python.testing.cwd": "${workspaceFolder}/tests",
22
+ // "python.testing.pytestPath": "${workspaceFolder}/.venv/bin/pytest",
23
+ // "python.testing.autoTestDiscoverOnSaveEnabled": true,
24
+ //
25
+ //
26
+ // we're going to use UVs virtual envs anyway, and VSCode doesn't seem to pick them up automatically
27
+ "python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
28
+ // ruff formatter
29
+ "ruff.importStrategy": "useBundled",
30
+ // Editor settings, Python specific
31
+ "[python]": {
32
+ "editor.defaultFormatter": "charliermarsh.ruff",
33
+ "editor.formatOnPaste": true,
34
+ "editor.formatOnSave": true,
35
+ "editor.formatOnSaveMode": "file",
36
+ },
37
+ "spellright.language": [
38
+ "en_GB"
39
+ ],
40
+ "spellright.documentTypes": [
41
+ "latex",
42
+ "plaintext",
43
+ "markdown"
44
+ ],
45
+ }
valn8n-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Bastien Chevreux
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
valn8n-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,167 @@
1
+ Metadata-Version: 2.4
2
+ Name: valn8n
3
+ Version: 0.1.0
4
+ Summary: A validator for n8n workflow JSON files
5
+ Project-URL: Homepage, https://github.com/DrMicrobit/valn8n
6
+ Project-URL: GitHub, https://github.com/DrMicrobit/valn8n
7
+ Project-URL: Issues, https://github.com/DrMicrobit/valn8n/issues
8
+ Author-email: Bastien Chevreux <bach@chevreux.org>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Requires-Python: >=3.13
17
+ Requires-Dist: json-source-map>=1.0.5
18
+ Requires-Dist: rich>=14.0.0
19
+ Description-Content-Type: text/markdown
20
+
21
+ # valn8n
22
+
23
+ A validator for [n8n](https://n8n.io/) workflow JSON files. Like `ruff` for Python, but for your n8n workflows.
24
+
25
+ Checks for errors, warning, and hints regarding syntax and semantics of workflows. Output in different formats (rich in terminal, text, JSON, CSV), most LLMs seem to work with 'text' quite well (tightly followed by JSON, but more tokens).
26
+
27
+ Also, `valn8n` allows me to asses the quality or hidden traps of workflows downloaded from the web, saving a lot of time not bothering with sometimes totally broken workflows.
28
+
29
+ ## Background
30
+
31
+ I have been testing n8n on and off with LLM assisted workflow generation and couldn't find a n8n workflow validator that would find whatever silly mistake an LLM (even flagship ones) could sometimes generate.
32
+
33
+ With `valn8n` however I can have the LLMs autocorrect those errors and am getting most n8n workflows as one-shot.
34
+
35
+ ## Requirements
36
+
37
+ - Python >= 3.13
38
+ - [uv](https://docs.astral.sh/uv/getting-started/installation/) package and project manager
39
+
40
+ ## Installation
41
+
42
+ ```bash
43
+ uv tool install valn8n
44
+ ```
45
+
46
+ ## Quick Start
47
+
48
+ ```bash
49
+ valn8n check my_workflow.json
50
+ valn8n check --strict-only my_workflow.json
51
+ ```
52
+
53
+ See also README in supplied demo workflows in `demo_valn8n/broken_vs_notbroken`.
54
+
55
+ ## Usage
56
+
57
+ ### Check a single file
58
+
59
+ ```bash
60
+ valn8n check workflow.json
61
+ ```
62
+
63
+ ### Check a directory
64
+
65
+ ```bash
66
+ valn8n check workflows/
67
+ ```
68
+
69
+ ### Select specific rules
70
+
71
+ Only check rules ND01xx and ND05xx.
72
+
73
+ ```bash
74
+ valn8n check --select ND01,ND05 workflow.json
75
+ ```
76
+
77
+ ### Ignore specific rules
78
+
79
+ Ignore ND05xx and ND0802.
80
+
81
+ ```bash
82
+ valn8n check --ignore ND05,ND0802 workflow.json
83
+ ```
84
+
85
+ ### Switching back on ignored rules
86
+
87
+ Ignore ND05xx but not ND0502.
88
+
89
+ ```bash
90
+ valn8n check --ignore ND05 --extend-select ND0502 workflow.json
91
+ ```
92
+
93
+ ### Strict-only mode
94
+
95
+ Run only strict rules, skipping advisory and hint rules:
96
+
97
+ ```bash
98
+ valn8n check --strict-only workflow.json
99
+ ```
100
+
101
+ ### JSON output (for CI)
102
+
103
+ ```bash
104
+ valn8n check --fmt json workflow.json
105
+ ```
106
+
107
+ ### Quiet mode (summary only)
108
+
109
+ ```bash
110
+ valn8n check -q workflow.json
111
+ ```
112
+
113
+ ### Tolerate unknown node keys
114
+
115
+ ```bash
116
+ valn8n check --tolerate-node-keys '*' workflow.json
117
+ ```
118
+
119
+ ### List all rules
120
+
121
+ ```bash
122
+ valn8n rule
123
+ ```
124
+
125
+ ## Output Formats
126
+
127
+ | Format | Flag | Description |
128
+ |--------|------|-------------|
129
+ | Rich | `--fmt rich` | Colored terminal output (default) |
130
+ | Text | `--fmt text` | Plain text |
131
+ | JSON | `--fmt json` | Machine-readable JSON |
132
+ | CSV | `--fmt csv` | Comma-separated values |
133
+ | List | `--fmt lst` | One diagnostic per line |
134
+
135
+ ## Exit Codes
136
+
137
+ | Code | Meaning |
138
+ |------|---------|
139
+ | 0 | No violations found |
140
+ | 1 | Violations found |
141
+ | 2 | Error (e.g. file not found, invalid arguments) |
142
+
143
+ ## Rules
144
+
145
+ | Group | Range | Description |
146
+ |-------|-------|-------------|
147
+ | IO | IO00xx | File I/O validation (read errors, invalid JSON) |
148
+ | ND01 | ND01xx | Filter operations (invalid ops, common mistakes) |
149
+ | ND02 | ND02xx | Node structure (unknown keys, value types, zero-property params) |
150
+ | ND03 | ND03xx | Parameter validation (deep param keys, param value types) |
151
+ | ND04 | ND04xx | Expression syntax (broken brackets, suspect prefixes) |
152
+ | ND05 | ND05xx | Credential validation (missing, empty, placeholder, leaking) |
153
+ | ND06 | ND06xx | Connection validation (unconnected inputs, dangling refs) |
154
+ | ND07 | ND07xx | Error handling (missing errorWorkflow, unhandled errors) |
155
+ | ND08 | ND08xx | Naming & documentation (default names, missing notes) |
156
+
157
+ Rules ND01xx-ND04xx and ND06xx are **strict** (structural correctness). ND05xx and 07xx are **advisory** (best practices). ND08xx are **hints** (atm only regarding naming clarity and documentation).
158
+
159
+ Note: in future this may change and strict/advisory might not be clean ranges anymore.
160
+
161
+ Use `--strict-only` to run only strict rules.
162
+
163
+ Run `valn8n rule` to see the full list with descriptions.
164
+
165
+ ## Contributing
166
+
167
+ I do not accept PRs with code changes at the moment. But feel free to post issues (with full workflows attached) in case you think there is an error in valn8n, or if you see an opportunity to improve it.
valn8n-0.1.0/README.md ADDED
@@ -0,0 +1,147 @@
1
+ # valn8n
2
+
3
+ A validator for [n8n](https://n8n.io/) workflow JSON files. Like `ruff` for Python, but for your n8n workflows.
4
+
5
+ Checks for errors, warning, and hints regarding syntax and semantics of workflows. Output in different formats (rich in terminal, text, JSON, CSV), most LLMs seem to work with 'text' quite well (tightly followed by JSON, but more tokens).
6
+
7
+ Also, `valn8n` allows me to asses the quality or hidden traps of workflows downloaded from the web, saving a lot of time not bothering with sometimes totally broken workflows.
8
+
9
+ ## Background
10
+
11
+ I have been testing n8n on and off with LLM assisted workflow generation and couldn't find a n8n workflow validator that would find whatever silly mistake an LLM (even flagship ones) could sometimes generate.
12
+
13
+ With `valn8n` however I can have the LLMs autocorrect those errors and am getting most n8n workflows as one-shot.
14
+
15
+ ## Requirements
16
+
17
+ - Python >= 3.13
18
+ - [uv](https://docs.astral.sh/uv/getting-started/installation/) package and project manager
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ uv tool install valn8n
24
+ ```
25
+
26
+ ## Quick Start
27
+
28
+ ```bash
29
+ valn8n check my_workflow.json
30
+ valn8n check --strict-only my_workflow.json
31
+ ```
32
+
33
+ See also README in supplied demo workflows in `demo_valn8n/broken_vs_notbroken`.
34
+
35
+ ## Usage
36
+
37
+ ### Check a single file
38
+
39
+ ```bash
40
+ valn8n check workflow.json
41
+ ```
42
+
43
+ ### Check a directory
44
+
45
+ ```bash
46
+ valn8n check workflows/
47
+ ```
48
+
49
+ ### Select specific rules
50
+
51
+ Only check rules ND01xx and ND05xx.
52
+
53
+ ```bash
54
+ valn8n check --select ND01,ND05 workflow.json
55
+ ```
56
+
57
+ ### Ignore specific rules
58
+
59
+ Ignore ND05xx and ND0802.
60
+
61
+ ```bash
62
+ valn8n check --ignore ND05,ND0802 workflow.json
63
+ ```
64
+
65
+ ### Switching back on ignored rules
66
+
67
+ Ignore ND05xx but not ND0502.
68
+
69
+ ```bash
70
+ valn8n check --ignore ND05 --extend-select ND0502 workflow.json
71
+ ```
72
+
73
+ ### Strict-only mode
74
+
75
+ Run only strict rules, skipping advisory and hint rules:
76
+
77
+ ```bash
78
+ valn8n check --strict-only workflow.json
79
+ ```
80
+
81
+ ### JSON output (for CI)
82
+
83
+ ```bash
84
+ valn8n check --fmt json workflow.json
85
+ ```
86
+
87
+ ### Quiet mode (summary only)
88
+
89
+ ```bash
90
+ valn8n check -q workflow.json
91
+ ```
92
+
93
+ ### Tolerate unknown node keys
94
+
95
+ ```bash
96
+ valn8n check --tolerate-node-keys '*' workflow.json
97
+ ```
98
+
99
+ ### List all rules
100
+
101
+ ```bash
102
+ valn8n rule
103
+ ```
104
+
105
+ ## Output Formats
106
+
107
+ | Format | Flag | Description |
108
+ |--------|------|-------------|
109
+ | Rich | `--fmt rich` | Colored terminal output (default) |
110
+ | Text | `--fmt text` | Plain text |
111
+ | JSON | `--fmt json` | Machine-readable JSON |
112
+ | CSV | `--fmt csv` | Comma-separated values |
113
+ | List | `--fmt lst` | One diagnostic per line |
114
+
115
+ ## Exit Codes
116
+
117
+ | Code | Meaning |
118
+ |------|---------|
119
+ | 0 | No violations found |
120
+ | 1 | Violations found |
121
+ | 2 | Error (e.g. file not found, invalid arguments) |
122
+
123
+ ## Rules
124
+
125
+ | Group | Range | Description |
126
+ |-------|-------|-------------|
127
+ | IO | IO00xx | File I/O validation (read errors, invalid JSON) |
128
+ | ND01 | ND01xx | Filter operations (invalid ops, common mistakes) |
129
+ | ND02 | ND02xx | Node structure (unknown keys, value types, zero-property params) |
130
+ | ND03 | ND03xx | Parameter validation (deep param keys, param value types) |
131
+ | ND04 | ND04xx | Expression syntax (broken brackets, suspect prefixes) |
132
+ | ND05 | ND05xx | Credential validation (missing, empty, placeholder, leaking) |
133
+ | ND06 | ND06xx | Connection validation (unconnected inputs, dangling refs) |
134
+ | ND07 | ND07xx | Error handling (missing errorWorkflow, unhandled errors) |
135
+ | ND08 | ND08xx | Naming & documentation (default names, missing notes) |
136
+
137
+ Rules ND01xx-ND04xx and ND06xx are **strict** (structural correctness). ND05xx and 07xx are **advisory** (best practices). ND08xx are **hints** (atm only regarding naming clarity and documentation).
138
+
139
+ Note: in future this may change and strict/advisory might not be clean ranges anymore.
140
+
141
+ Use `--strict-only` to run only strict rules.
142
+
143
+ Run `valn8n rule` to see the full list with descriptions.
144
+
145
+ ## Contributing
146
+
147
+ I do not accept PRs with code changes at the moment. But feel free to post issues (with full workflows attached) in case you think there is an error in valn8n, or if you see an opportunity to improve it.
@@ -0,0 +1,17 @@
1
+ # Demo
2
+
3
+ ## Comparison 'less-broken' vs 'totally broken' workflow
4
+
5
+ We'll just look at 'strict' rules of `valn8n`. Run `valn8n check --strict-only lessbroken_3859-ai-customer-support-assistant-whatsapp-ready-works-for-any-business.json` which will result in one error (a wait between trials parameter apparently has a null value where it should have an int).
6
+
7
+ Now compare with the proken version: `valn8n check --strict-only broken_1521_Whatsapp_Stickynote_Automation_Webhook.json` which has 42 errors, 13 warnings. Ouch. Feel free to paste both workflows into the n8n editor to also see the difference there.
8
+
9
+ ## Sources
10
+
11
+ ### Broken workflow
12
+
13
+ `curl -L https://raw.githubusercontent.com/Zie619/n8n-workflows/main/workflows/Whatsapp/1521_Whatsapp_Stickynote_Automation_Webhook.json -o broken_1521_Whatsapp_Stickynote_Automation_Webhook.json`
14
+
15
+ ### Less broken workflow
16
+
17
+ Downloaded on 15.03.2026 from: https://n8n.io/workflows/3859-ai-customer-support-assistant-whatsapp-ready-works-for-any-business/