{"record":{"id":"13da999f731cdfa9","repo":"n8n-io/n8n","slug":"invalid-categor-invalidcategories-length-1-i","errorCode":null,"errorMessage":"Invalid categor${invalidCategories.length > 1 ? 'ies' : 'y'} received: ${invalidCategories.join(', ')}. Valid categories are: ${RISK_CATEGORIES.join(', ')}","messagePattern":"Invalid categor(.+?) received: (.+?)\\. Valid categories are: (.+?)","errorType":"validation","errorClass":"UserError","httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/audit.ts","lineNumber":71,"sourceCode":"\t}\n\n\tasync run() {\n\t\tconst { flags: auditFlags } = this;\n\t\tconst categories =\n\t\t\tauditFlags.categories?.split(',').filter((c): c is Risk.Category => c !== '') ??\n\t\t\tRISK_CATEGORIES;\n\n\t\tconst invalidCategories = categories.filter((c) => !RISK_CATEGORIES.includes(c));\n\n\t\tif (invalidCategories.length > 0) {\n\t\t\tconst message =\n\t\t\t\tinvalidCategories.length > 1\n\t\t\t\t\t? `Invalid categories received: ${invalidCategories.join(', ')}`\n\t\t\t\t\t: `Invalid category received: ${invalidCategories[0]}`;\n\n\t\t\tconst hint = `Valid categories are: ${RISK_CATEGORIES.join(', ')}`;\n\n\t\t\tthrow new UserError([message, hint].join('. '));\n\t\t}\n\n\t\tconst { SecurityAuditService } = await import('@/security-audit/security-audit.service.js');\n\n\t\tconst result = await Container.get(SecurityAuditService).run(\n\t\t\tcategories,\n\t\t\tauditFlags['days-abandoned-workflow'],\n\t\t);\n\n\t\tif (Array.isArray(result) && result.length === 0) {\n\t\t\tthis.logger.info('No security issues found');\n\t\t} else {\n\t\t\tprocess.stdout.write(JSON.stringify(result, null, 2));\n\t\t}\n\t}\n\n\tasync catch(error: Error) {\n\t\tthis.logger.error('Failed to generate security audit');","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/cli/src/commands/audit.ts#L53-L89","documentation":"The `n8n audit` command throws UserError when one or more --categories values are not in RISK_CATEGORIES. The message lists the invalid categories and the valid set, joined with '. '. Stops the audit before invoking SecurityAuditService.","triggerScenarios":"Running `n8n audit --categories=<x>` where <x> (or one of a comma list) is not a member of RISK_CATEGORIES (e.g. typo like 'database' instead of the supported key).","commonSituations":"Typo in the category name; using a category from an older/newer n8n version; copy-pasted command with a stale category list.","solutions":["Run `n8n audit --help` (or check RISK_CATEGORIES in source) and pass only valid categories.","Omit --categories to run the default audit set.","Upgrade/downgrade align expectations: confirm the supported category list for your n8n version."],"exampleFix":"# before\nn8n audit --categories=database,credentials\n\n# after (use valid category names)\nn8n audit --categories=credentials,_nodes,filesystem","handlingStrategy":"validation","validationCode":"import { RISK_CATEGORIES } from '@/commands/audit'; // or hardcode the valid set\nconst valid = categories.filter((c) => RISK_CATEGORIES.includes(c));\nif (valid.length !== categories.length) { /* reject before running audit */ }","typeGuard":"function isInvalidCategoryError(error: unknown): boolean {\n  return error instanceof Error && error.message.startsWith('Invalid categor');\n}","tryCatchPattern":"try {\n  await Audit.run(argv);\n} catch (e) {\n  if (isInvalidCategoryError(e)) { /* show valid categories from message and re-invoke */ }\n  else throw e;\n}","preventionTips":["Check `n8n audit --help` for the supported category list for your n8n version.","Omit --categories to use defaults.","Pin scripts to a specific n8n version to avoid category-set drift."],"tags":["cli","audit","validation","user-error"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}