Well-Architected anti-patterns
vulkro-sf antipatterns finds Salesforce Well-Architected anti-patterns in Apex: code that will hit governor limits, fail at scale, or be hard to maintain. These are architecture findings, not security findings, so they are kept out of vulkro-sf scan and the readiness report.
vulkro-sf antipatterns ./force-app
vulkro-sf antipatterns ./force-app --format sarif > antipatterns.sarif
A SOQL query inside a loop (AP-001) is a reliability problem, not an exploit. Keeping the two streams apart keeps security triage clean, and each has its own audience: reviewers read the security output, architects and leads read this one.
The core series
IDs are permanent once shipped.
| ID | Pillar | Pattern |
|---|---|---|
| AP-001 | Trusted / Reliable | SOQL query inside a loop |
| AP-002 | Trusted / Reliable | DML statement inside a loop |
| AP-003 | Adaptable | Hardcoded Salesforce record ID |
| AP-004 | Trusted / Reliable | Empty or comment-only catch block |
| AP-005 | Adaptable / Composable | Logic in the trigger body instead of a handler |
| AP-006 | Trusted / Reliable | @future inside a trigger |
| AP-007 | Trusted / Reliable | Production class with no apparent test class |
| AP-008 | Easy / Automated | Schema describe call inside a loop |
| AP-009 | Adaptable / Composable | More than one trigger on the same object |
| AP-010 | Trusted / Reliable | Trigger does DML on Trigger.new / Trigger.old (recursion risk) |
| AP-011 | Trusted / Reliable | Mixed DML: setup and non-setup objects in one transaction |
| AP-012 | Adaptable / Composable | Hardcoded callout URL instead of a Named Credential |
| AP-013 | Trusted / Reliable | SOQL with no WHERE and no LIMIT |
| AP-014 | Trusted / Reliable | @isTest(SeeAllData=true) |
The command reports many more IDs beyond these (async design, callouts, Flow, Agentforce actions and others). vulkro-sf antipatterns --help and the CLI reference list them.
Resource Optimiser group
The governor-limit rules, for example AP-001, AP-002, AP-008, AP-013, AP-059 (callout in a loop), AP-065 (@future per record), AP-071 (System.enqueueJob in a loop), AP-072 (unbounded batch start() query) and AP-073 (too many SOQL or DML statements in one method), are tagged (Resource Optimiser) in table output. It is a display label only: the pillar field in JSON, SARIF and JUnit stays Trusted (Reliable).
Options
| Flag | What it does |
|---|---|
--format <fmt> | table (default), json, sarif or junit. |
--exclude-namespace <ns> | Treat extra namespaces as your own (merged-package projects). |
--compliance hipaa,pci | Broaden the PII identifiers some rules look for. |
--no-cache, --cache-dir <dir> | Control the per-file result cache. |
Exit codes
0 no anti-patterns; 1 anti-patterns reported (or no licence); 2 error.
Gate security findings on every pull request, and anti-patterns on nightly or release builds: they rarely need to block one change.
See also: Anti-patterns report, Methodology, Salesforce Well-Architected