@lwc/lwc-platform/no-aura |
Stock Code Analyzer ESLint |
No $A, Aura, Sfdc, or sforce in a Lightning web component |
@lwc/lwc-platform/no-aura-libs |
Stock Code Analyzer ESLint |
No import of an Aura library in a Lightning web component |
@lwc/lwc-platform/no-inline-disable |
Stock Code Analyzer ESLint |
No comment that switches off an ESLint rule for a line |
@lwc/lwc/no-inner-html |
Stock Code Analyzer ESLint |
No HTML set from a string: no innerHTML, outerHTML, or insertAdjacentHTML |
@salesforce-ux/slds/enforce-bem-usage |
Stock Code Analyzer ESLint |
An SLDS class modifier takes a single underscore, as in slds-button_brand, not a double dash |
@salesforce-ux/slds/enforce-component-hook-naming-convention |
Stock Code Analyzer ESLint |
A component styling hook has its current SLDS 2 name |
@salesforce-ux/slds/enforce-sds-to-slds-hooks |
Stock Code Analyzer ESLint |
No legacy --sds- styling hook; use the --slds- hook of the same name |
@salesforce-ux/slds/lwc-token-to-slds-hook |
Stock Code Analyzer ESLint |
No deprecated --lwc- design token; use the matching SLDS 2 styling hook, with the token as its fallback value |
@salesforce-ux/slds/modal-close-button-issue |
Stock Code Analyzer ESLint |
A modal close button follows the SLDS modal blueprint |
@salesforce-ux/slds/no-deprecated-classes-slds2 |
Stock Code Analyzer ESLint |
No class that SLDS 2 does not have |
@salesforce-ux/slds/no-hardcoded-values-slds2 |
Stock Code Analyzer ESLint |
Colours, spacing, and type sizes come from SLDS 2 styling hooks, not from hard-coded values |
@salesforce-ux/slds/no-slds-class-overrides |
Stock Code Analyzer ESLint |
No override of an SLDS class; give the component a class of its own |
@salesforce-ux/slds/no-slds-namespace-for-custom-hooks |
Stock Code Analyzer ESLint |
A custom styling hook has a name in the component's own namespace, not in --slds- or --sds- |
@salesforce-ux/slds/no-slds-private-var |
Stock Code Analyzer ESLint |
No private SLDS styling hook, one whose name starts with --_slds- or --slds-s- |
@salesforce-ux/slds/no-slds-var-without-fallback |
Stock Code Analyzer ESLint |
Every SLDS styling hook in var() has a fallback value |
@salesforce-ux/slds/no-sldshook-fallback-for-lwctoken |
Stock Code Analyzer ESLint |
An --slds- styling hook is never the fallback value of an --lwc- design token |
@salesforce-ux/slds/no-unsupported-hooks-slds2 |
Stock Code Analyzer ESLint |
No styling hook that SLDS 2 does not have |
@salesforce-ux/slds/reduce-annotations |
Stock Code Analyzer ESLint |
No SLDS linter suppression without an approving review from the owning team |
AbstractClassWithoutAnyMethodApex |
Custom PMD XPath |
An abstract class declares a method or a constructor |
AnnotationsNamingConventions |
Stock PMD |
Write annotations in Pascal case: @IsTest, not @isTest |
ApexAssertionsShouldIncludeMessage |
Stock PMD |
Every assertion includes a message that says what went wrong, Assert.fail() included |
ApexBadCrypto |
Stock PMD |
Generate encryption keys and initialisation vectors; never write them into the code |
ApexCSRF |
Stock PMD |
Code that runs when a page loads changes no data: no DML in a constructor, an initializer block, or an init method |
ApexDangerousMethods |
Stock PMD |
No debug statement writes a credential, and no call to Configuration.disableTriggerCRUDSecurity() |
ApexDoc |
Stock PMD |
Every class, method, and property has an ApexDoc comment with a description, a @param for each parameter, and a @return where a value is returned |
ApexDocDescriptionLength |
Custom PMD XPath |
Every ApexDoc description has at least 10 characters that say what the thing is for |
ApexFlsViolation |
Stock Code Analyzer SFGE |
Every query and DML statement on a path from an entry point runs in user mode or behind a permission check |
apexguru-other |
Stock Code Analyzer ApexGuru |
A finding of a new ApexGuru rule is reported for information until these standards place it |
ApexInsecureEndpoint |
Stock PMD |
A callout goes over HTTPS; no http:// endpoint |
ApexNullPointerException |
Stock Code Analyzer SFGE |
No operation on a value that may be null; assign it or check it first |
ApexOpenRedirect |
Stock PMD |
A redirect goes to a page that the code chooses, never to a URL parameter as it is |
ApexSOQLInjection |
Stock PMD |
No input is joined into a query string; use bind variables, an allowlist, or String.escapeSingleQuotes |
ApexSuggestUsingNamedCred |
Stock PMD |
Do not set the Authorization header directly; use a Named Credential |
ApexUnitTestClassShouldHaveAsserts |
Stock PMD |
Every test method asserts the behaviour it exercises |
ApexUnitTestClassShouldHaveRunAs |
Stock PMD |
A test calls System.runAs for every user persona that reaches the code |
ApexUnitTestMethodShouldHaveIsTestAnnotation |
Stock PMD |
No testMethod keyword; mark a test method with @IsTest |
ApexUnitTestShouldNotUseSeeAllDataTrue |
Stock PMD |
Do not use @IsTest(SeeAllData=true); a test creates the data it needs |
ApexXSSFromEscapeFalse |
Stock PMD |
An addError message that is not escaped holds no value that a user entered |
ApexXSSFromURLParam |
Stock PMD |
Escape or validate a value read from a URL parameter before the class uses or returns it |
AssignmentInOperand |
Stock PMD |
No assignment in a condition: no =, ++, or -- in an if, while, do, for, or ternary test |
AuraEnabledControllerNaming |
Custom PMD XPath |
A class that a Lightning component calls ends in Controller |
AvoidAbsoluteSalesforceUrl |
Custom PMD XPath |
No absolute URL of a Salesforce org in Apex; use a page reference or a relative URL |
AvoidAbsoluteSalesforceUrlFlow |
Custom PMD XPath |
No absolute URL of a Salesforce org in a Flow; use a relative URL |
AvoidAbsoluteSalesforceUrlHtml |
Custom PMD XPath |
Lightning markup holds no absolute URL of a Salesforce org |
AvoidAbsoluteSalesforceUrlVf |
Custom PMD XPath |
A Visualforce page holds no absolute URL of a Salesforce org |
AvoidApiSessionIdInApexString |
Custom PMD XPath |
Apex does not write {!$Api.Session_ID} into a string |
AvoidAuraWithLockerDisabled |
Stock Code Analyzer PMD |
Every Aura component is at API version 40.0 or later |
AvoidBooleanMethodParameters |
Stock PMD |
No Boolean parameter that switches what a public or global method does; use two methods or an enum |
AvoidConsoleStatements |
Stock PMD |
No console statements, in a component or in a Jest test |
AvoidDatabaseOperationInLoop |
Stock Code Analyzer SFGE |
No query or DML statement inside a loop, in the loop or in a method it calls |
AvoidDebugStatements |
Stock PMD |
No System.debug statements, in production code or in a test class |
AvoidDeeplyNestedIfStmts |
Stock PMD |
No deeply nested if statements |
AvoidDescribeInLoops |
Custom PMD XPath |
Make a describe call whose result does not change once, before the loop |
AvoidDirectAccessTriggerMap |
Stock PMD |
No fixed index on Trigger.new or Trigger.old, such as Trigger.new[0] |
AvoidFlowActionInLoop |
Custom PMD XPath |
No action inside a Flow loop; call it once, after the loop, with a collection |
AvoidFutureAnnotation |
Stock PMD |
Start asynchronous work as a Queueable job, not a future method |
AvoidGetHeapSizeInLoop |
Stock Code Analyzer Regex |
No Limits.getHeapSize() inside a loop |
AvoidGlobalModifier |
Stock PMD |
global only where another namespace or the platform requires it |
AvoidHardCodedCredentialsInAura |
Stock Code Analyzer PMD |
No credential as the default value of an aura:attribute |
AvoidHardcodedCredentialsInFieldDecls |
Stock Code Analyzer PMD |
No credential in a field declaration; keep passwords, keys, and tokens in an External Credential |
AvoidHardcodedCredentialsInHttpHeader |
Stock Code Analyzer PMD |
No credential is written into a request header |
AvoidHardcodedCredentialsInSetPassword |
Stock Code Analyzer PMD |
No password is written into a call to System.setPassword |
AvoidHardcodedCredentialsInVarAssign |
Stock Code Analyzer PMD |
No credential assigned to a variable as a text literal |
AvoidHardcodedCredentialsInVarDecls |
Stock Code Analyzer PMD |
No credential in a variable declaration as a text literal |
AvoidHardcodedIdFlow |
Custom PMD XPath |
No record ID is written into a Flow |
AvoidHardcodedIdVf |
Custom PMD XPath |
A Visualforce link does not point to a hard-coded record Id |
AvoidHardcodedIpAddressApex |
Custom PMD XPath |
No IP address is written into Apex; read it from a Named Credential, custom metadata, or a custom setting |
AvoidHardcodedIpAddressMetadata |
Custom PMD XPath |
No endpoint in integration metadata is an IP address |
AvoidHardcodedPageLinkVf |
Custom PMD XPath |
Link to a Visualforce page with $Page, not an /apex/ path |
AvoidHardcodedResourcePathVf |
Custom PMD XPath |
Reference a static resource through $Resource, not a /resource/ path |
AvoidHardcodedSecretSalesforce |
Custom PMD XPath |
No secret is written into metadata, with one rule for each form of secret |
AvoidHardcodedSecretsInVFAttrs |
Stock Code Analyzer PMD |
No credential as the default value of an apex:attribute |
AvoidHardcodingId |
Stock PMD |
No record ID is written into Apex; find the record by DeveloperName, an external ID, or a name |
AvoidHttpReferer |
Custom PMD XPath |
No security decision from the HTTP Referer header |
AvoidIframeVf |
Custom PMD XPath |
A Visualforce page does not frame another page |
AvoidInlineStyles |
Stock PMD |
Styling lives in a stylesheet, not in an inline style attribute |
AvoidInlineStylesInVisualforce |
Custom PMD XPath |
No style element, and no style, labelStyle, or html-style attribute, in a Visualforce page or component |
AvoidInsecureCookies |
Custom PMD XPath |
Create a cookie with isSecure set to true |
AvoidInterfaceAsMapKey |
Stock PMD |
No interface as a Map key type where an abstract class implements it and defines equals or hashCode |
AvoidJavaScriptUrlHtmlLwcAura |
Custom PMD XPath |
No attribute in Lightning markup or plain HTML holds a javascript: URL, except javascript:void(0) |
AvoidJavaScriptUrlVf |
Custom PMD XPath |
No attribute in Visualforce holds a javascript: URL, except javascript:void(0) |
AvoidLmcIsExposedTrue |
Stock Code Analyzer PMD |
A Lightning Message Channel is exposed only when a component in another namespace has to use it |
AvoidLogicInTrigger |
Stock PMD |
A trigger holds no logic: no if, switch, loop, or try block |
AvoidLwcBubblesComposedTrue |
Stock Code Analyzer PMD |
No custom event with both bubbles and composed set to true |
AvoidMagicNumbers |
Custom PMD XPath |
Declare a value once as a constant (static final); no magic numbers other than 0, 1, and -1 |
AvoidMultipleFormsVf |
Custom PMD XPath |
A Visualforce page or component has one apex:form |
AvoidMultipleMassSchemaLookups |
Stock Code Analyzer SFGE |
No Schema.getGlobalDescribe() or Schema.describeSObjects() inside a loop, or twice on one path |
AvoidNestedFlowLoops |
Custom PMD XPath |
No Flow loop inside another loop |
AvoidNestedSwitchStmts |
Custom PMD XPath |
No switch inside a switch |
AvoidNonExistentAnnotations |
Stock PMD |
Every annotation is one that Apex defines |
AvoidNonRestrictiveQueries |
Stock PMD |
Every SOQL query and SOSL search has a WHERE clause or a LIMIT |
AvoidNonSelectiveSoqlFilter |
Custom PMD XPath |
Write filters that can use an index; no NOT IN, !=, or LIKE with a leading wildcard |
AvoidOldSalesforceApiVersions |
Stock Code Analyzer Regex |
Every metadata file states a recent API version |
AvoidRecordTypeInfosByName |
Custom PMD XPath |
Do not call getRecordTypeInfosByName(); use getRecordTypeInfosByDeveloperName() |
AvoidSControls |
Stock Code Analyzer PMD |
No s-control is committed; rebuild it as a Visualforce page or a Lightning web component |
AvoidSizeOfSoql |
Custom PMD XPath |
Count records with an aggregate query, not size() on a query |
AvoidStatefulDatabaseResult |
Stock PMD |
A Database.Stateful batch class keeps no Database result, such as a SaveResult, in an instance field |
AvoidTermsWithImplicitBias |
Stock Code Analyzer Regex |
Language is inclusive: allowlist and denylist, never whitelist and blacklist |
AvoidTrailingComma |
Stock PMD |
No trailing comma after the last item of an object literal or an array literal |
AvoidTrivialPropertyGetters |
Custom PMD XPath |
A value that is only read is a property, not a field with a getter method |
AvoidUnauthorizedApiSessionIdInApex |
Stock Code Analyzer PMD |
Apex does not write the session Id into a string |
AvoidUnauthorizedApiSessionIdInVisualforce |
Stock Code Analyzer PMD |
A Visualforce page does not read $Api.Session_ID |
AvoidUnauthorizedGetSessionIdInApex |
Stock Code Analyzer PMD |
Apex does not read the session Id; no UserInfo.getSessionId() |
AvoidUnauthorizedGetSessionIdInVisualforce |
Stock Code Analyzer PMD |
A Visualforce page does not call GETSESSIONID() |
AvoidUsingTestIsRunningTest |
Custom PMD XPath |
Production code does not call Test.isRunningTest() |
AvoidWeakCryptoAlgorithms |
Custom PMD XPath |
Use an algorithm of the SHA-2 family for a digest, a MAC, or a signature; no MD5 or SHA-1 |
AvoidWithStatement |
Stock PMD |
No with statement |
BooleanGetMethodNameApex |
Custom PMD XPath |
A Boolean method is named as a question, not with get |
BrokenNullCheckApex |
Custom PMD XPath |
A null check does not read the value it checks for null |
BumpApiVersion |
Custom PMD XPath |
Every metadata file is at or above the API version floor |
BusyLoopDelay |
Stock Code Analyzer ApexGuru |
No loop written to pass time; use a delayed Queueable job or a scheduled job |
ButtonWithoutNameHtmlLwcAura |
Custom PMD XPath |
Every image button, icon button, and image-map link has a name that a screen reader can announce |
ButtonWithoutNameVf |
Custom PMD XPath |
Every image button and image-map link in a Visualforce page has a name that a screen reader can announce |
CheckboxFieldNamePrefix |
Custom PMD XPath |
A checkbox field name starts with Is, never with IsNot |
ClassNamingConventions |
Stock PMD |
Class, interface, and enum names are in Pascal case |
CognitiveComplexity |
Stock PMD |
Keep the cognitive complexity of a method low |
CombineNestedIfStatements |
Custom PMD XPath |
Combine nested if statements with nothing else in the outer one into one if with && |
complexity |
Stock Code Analyzer ESLint |
A function has a cyclomatic complexity of 10 or less |
consistent-return |
Stock Code Analyzer ESLint |
A function returns a value on every path, or on none |
ConsistentReturn |
Stock PMD |
A function returns a value on every path, or on none |
CopyingListOrSetElementsUsingAForLoop |
Stock Code Analyzer ApexGuru |
Copy a list or a set with addAll(), not element by element in a loop |
curly |
Stock Code Analyzer ESLint |
Wrap the body of every if, else, for, and while in braces, even one line |
CyclicSubflow |
Stock Code Analyzer Flow |
No subflow calls, directly or through a chain, a Flow that called it |
CyclomaticComplexity |
Stock PMD |
Keep the cyclomatic complexity of a method low |
DatabaseOperationsMustUseWithSharing |
Stock Code Analyzer SFGE |
Every database operation runs under a stated sharing declaration along the whole call path |
DbInLoop |
Stock Code Analyzer Flow |
No Get, Create, Update, or Delete Records element inside a Flow loop |
DebugsShouldUseLoggingLevel |
Stock PMD |
Any debug statement that remains specifies a LoggingLevel |
DeclareAccessOnMethods |
Custom PMD XPath |
Every method except a test method declares its access modifier |
DefaultCopy |
Stock Code Analyzer Flow |
An element pasted in Flow Builder is renamed and reviewed |
DeprecatedDocumentationRequired |
Custom PMD XPath |
Every element with the @Deprecated annotation has a @deprecated tag with the reason and the alternative |
DetectCopyPasteForApex |
Stock Code Analyzer CPD |
No copied blocks of Apex; share a method or a base class |
DetectCopyPasteForHtml |
Stock Code Analyzer CPD |
No copied blocks of HTML markup; share a component |
DetectCopyPasteForJavascript |
Stock Code Analyzer CPD |
No copied blocks of JavaScript; share a function in a module |
DetectCopyPasteForTypescript |
Stock Code Analyzer CPD |
No copied blocks of TypeScript; share a function in a module |
DetectCopyPasteForVisualforce |
Stock Code Analyzer CPD |
No copied blocks of Visualforce markup; share a component |
DetectCopyPasteForXml |
Stock Code Analyzer CPD |
No block of metadata XML copied by hand from one file to another |
DmlInALoop |
Stock Code Analyzer ApexGuru |
No DML statement inside a loop |
DmlInLoopAcrossMethods |
Custom PMD XPath |
No call inside a loop to a method that runs DML |
DoNotRunAsCurrentUser |
Custom PMD XPath |
A test never runs as the current user |
DoNotRunFlowInSystemMode |
Custom PMD XPath |
A Flow runs in user context; system context is a reviewed exception |
DoNotUseProcessBuilder |
Custom PMD XPath |
No automation is built in Process Builder; rebuild every process as a Flow |
DoNotUseWithoutSharing |
Custom PMD XPath |
without sharing is a deliberate, justified exception |
DoNotUseWorkflow |
Custom PMD XPath |
No automation is built as a Workflow Rule; rebuild every rule as a Flow |
EagerlyLoadedDescribeSObjectResult |
Stock PMD |
Load describe results lazily with SObjectDescribeOptions.DEFERRED |
EmailAddressInLiteral |
Custom PMD XPath |
No email address written into Apex |
EmptyCatchBlock |
Stock PMD |
No empty catch block |
EmptyIfStmt |
Stock PMD |
No empty if block |
EmptyInitializer |
Custom PMD XPath |
No empty instance initializer block |
EmptyStatementBlock |
Stock PMD |
No empty method or block, except a private no-argument constructor, a virtual base method, and a commented when else |
EmptyTryOrFinallyBlock |
Stock PMD |
No empty try or finally block |
EmptyWhileStmt |
Stock PMD |
No empty while block |
eqeqeq |
Stock Code Analyzer ESLint |
Compare values with === and !==, not == and !=; value == null is the one exception |
EqualComparison |
Stock PMD |
Compare values with === and !==, not == and !=; value == null is the one exception |
ExceptionDocumentationRequired |
Custom PMD XPath |
A method comment names each exception it throws with @throws |
ExpensiveDebugStatements |
Stock Code Analyzer ApexGuru |
No debug statement whose argument is expensive to build |
ExpensiveMethods |
Stock Code Analyzer ApexGuru |
Refactor a method that uses a large share of the org's CPU time |
ExpensiveStringComparison |
Stock Code Analyzer ApexGuru |
Compare strings with equals or equalsIgnoreCase, not == |
FieldDeclarationsShouldBeAtStart |
Stock PMD |
Declare fields before the first method of a class |
FieldNameMatchesClassName |
Custom PMD XPath |
A field or property does not take the name of its class, and a local variable does not take the name of a class |
FieldNameMatchesMethodName |
Custom PMD XPath |
A field or property does not share its name with a method of its class |
FieldNamingConventions |
Stock PMD |
Field names are in camel case, and constant and enum value names in upper snake case |
FieldsetWithoutLegendHtml |
Custom PMD XPath |
A fieldset has a legend that names its group of controls |
FieldsetWithoutLegendVf |
Custom PMD XPath |
A fieldset in a Visualforce page has a legend that names its group of controls |
FixDuplicateConditions |
Custom PMD XPath |
Each branch of an if / else if chain tests a different condition |
FlagSystemMode |
Custom PMD Java |
User mode is the default; a system-mode operation is a deliberate exception, with its reason in a comment |
FlowAllowBackAfterRecordChange |
Custom PMD XPath |
A screen after a record change does not offer the Previous button |
FlowDecisionQuestion |
Custom PMD XPath |
A Decision's label is the question it answers, and ends with a question mark |
FlowDeployAsActiveNotEnabled |
Custom PMD XPath |
The Flow settings file does not switch off deploy as active |
FlowDraft |
Custom PMD XPath |
Activate a Flow that has never been activated |
FlowElementVerb |
Custom PMD XPath |
A Flow element's name starts with the verb for its type |
FlowGetRecordsAllFields |
Custom PMD XPath |
A Get Records element names the fields that the Flow uses |
FlowGetRecordsWithoutFaultPath |
Custom PMD XPath |
A Get Records element has a fault path |
FlowGetRecordsWithoutFilter |
Custom PMD XPath |
A Get Records element has a filter |
FlowGetRecordsWithoutNullCheck |
Custom PMD XPath |
A Flow checks the result of a Get Records element for null before it uses it |
FlowMissingTriggerOrder |
Custom PMD XPath |
Every record-triggered Flow has a trigger order |
FlowNameConvention |
Custom PMD XPath |
A Flow's name has four parts: the owner code, the object, the kind code, and the purpose |
FlowNotAutoLayout |
Custom PMD XPath |
A Flow is built in auto-layout |
FlowResourcePrefix |
Custom PMD XPath |
A Flow resource's name starts with the prefix for its type |
ForLoopsMustUseBraces |
Stock PMD |
Wrap the body of every for loop in braces, even one line |
FormalParameterNamingConventions |
Stock PMD |
Parameter names are in camel case |
FrameWithoutTitleHtml |
Custom PMD XPath |
An iframe or a frame has a title that says what it holds |
FrameWithoutTitleVf |
Custom PMD XPath |
An iframe, a frame, or an apex:iframe in a Visualforce page has a title that says what it holds |
HotspotDeserializeJson |
Custom PMD XPath |
Every place that reads JSON is reviewed |
HotspotEncrypt |
Custom PMD XPath |
Every call that encrypts or decrypts is reviewed |
IdempotentOperationsApex |
Custom PMD XPath |
No assignment of a value to itself |
IfElseStmtsMustUseBraces |
Stock PMD |
Wrap the body of every else in braces, even one line |
IfStmtsMustUseBraces |
Stock PMD |
Wrap the body of every if in braces, even one line |
ImageWithEmptyAltHtmlLwcAura |
Custom PMD XPath |
Only a decorative image has an empty alternative text |
ImageWithEmptyAltVf |
Custom PMD XPath |
Only a decorative image in a Visualforce page has an empty alt |
ImageWithoutAltHtmlLwcAura |
Custom PMD XPath |
Every image has an alternative text attribute |
ImageWithoutAltVf |
Custom PMD XPath |
Every image in a Visualforce page has an alt attribute |
InaccessibleAuraEnabledGetter |
Stock PMD |
The getter of an @AuraEnabled property is public or global |
InefficientEmptyStringCheckApex |
Custom PMD XPath |
Test for a blank string with String.isBlank |
InvocableClassNoArgConstructor |
Stock PMD |
A class with an @InvocableVariable member and an explicit constructor also has a visible no-argument constructor |
LayoutTableHtml |
Custom PMD XPath |
No table is used for layout |
LayoutTableVf |
Custom PMD XPath |
No table is used for layout in a Visualforce page |
LayoutTableWithSemanticMarkupHtml |
Custom PMD XPath |
A layout table carries no caption, th, summary, headers, or scope |
LayoutTableWithSemanticMarkupVf |
Custom PMD XPath |
A layout table in a Visualforce page carries no caption, th, summary, headers, or scope |
LibraryWithKnownCriticalSeverityVulnerability |
Stock Code Analyzer RetireJS |
No JavaScript library with a known vulnerability of critical severity |
LibraryWithKnownHighSeverityVulnerability |
Stock Code Analyzer RetireJS |
No JavaScript library with a known vulnerability of high severity |
LibraryWithKnownLowSeverityVulnerability |
Stock Code Analyzer RetireJS |
No JavaScript library with a known vulnerability of low severity |
LibraryWithKnownMediumSeverityVulnerability |
Stock Code Analyzer RetireJS |
No JavaScript library with a known vulnerability of medium severity |
LightningWebSecurityNotEnabled |
Custom PMD XPath |
The Security settings file does not switch off Lightning Web Security or its stricter Content Security Policy |
LimitsGetHeapsizeMethods |
Stock Code Analyzer ApexGuru |
Limits.getHeapSize() is not called often |
ListItemOutsideListHtml |
Custom PMD XPath |
A list item is inside a list: an li in a ul, ol, or menu, and a dt or dd in a dl |
ListItemOutsideListVf |
Custom PMD XPath |
A list item in a Visualforce page is inside a list |
LoadCSSApexStylesheet |
Stock Code Analyzer PMD |
An apex:stylesheet loads a stylesheet from a static resource |
LoadCSSLinkHref |
Stock Code Analyzer PMD |
A link tag in a Visualforce page loads a stylesheet from a static resource |
LoadJavaScriptHtmlScript |
Stock Code Analyzer PMD |
A script tag in a Visualforce page loads JavaScript from a static resource |
LoadJavaScriptIncludeScript |
Stock Code Analyzer PMD |
An apex:includeScript loads JavaScript from a static resource |
LocalVariableNamingConventions |
Stock PMD |
Local variable names are in camel case |
LogicInversionApex |
Custom PMD XPath |
Negate a comparison with the opposite operator |
ManageUsers |
Custom PMD XPath |
No profile or permission set grants ManageUsers |
MasterDetailReparentable |
Custom PMD XPath |
A master-detail field that does not allow reparenting is a choice made on purpose |
max-depth |
Stock Code Analyzer ESLint |
Blocks nest no more than 3 deep in a function |
max-lines-per-function |
Stock Code Analyzer ESLint |
A function has no more than 50 lines of code, not counting blank lines and comments |
MetadataDescriptionAnalytics |
Custom PMD XPath |
A report, dashboard, or analytics asset carries a description of more than 10 characters, where the organisation asks for one |
MetadataDescriptionComponent |
Custom PMD XPath |
Every component carries a description of more than 10 characters |
MetadataDescriptionCore |
Custom PMD XPath |
Every component of the data model, and every process on it, carries a description of more than 10 characters |
MetadataDescriptionCustomField |
Custom PMD XPath |
Every custom field carries a description of more than 10 characters |
MetadataDescriptionCustomObject |
Custom PMD XPath |
Every custom object carries a description of more than 10 characters |
MetadataDescriptionData |
Custom PMD XPath |
Every data quality component carries a description of more than 10 characters |
MetadataDescriptionEinstein |
Custom PMD XPath |
Every agent or Einstein component carries a description of more than 10 characters |
MetadataDescriptionFlow |
Custom PMD XPath |
Every Flow, Flow test, Flow category, and Flow value map carries a description of more than 10 characters |
MetadataDescriptionIntegration |
Custom PMD XPath |
Every integration component carries a description of more than 10 characters |
MetadataDescriptionPermission |
Custom PMD XPath |
Every permission set, profile, custom permission, permission set group, muting permission set, and user access policy carries a description of more than 10 characters |
MetadataDescriptionSharing |
Custom PMD XPath |
Every sharing or access component, and every sharing rule, carries a description of more than 10 characters |
MetadataDescriptionStandardField |
Custom PMD XPath |
A standard field that the org uses in its own way carries a description of more than 10 characters |
MetadataDescriptionUserInterface |
Custom PMD XPath |
Every user interface or code component carries a description of more than 10 characters |
MetadataLabelStartsWithCapital |
Custom PMD XPath |
Every label of a Flow, a custom object, or a custom field starts with a capital letter |
MetadataNameStartsWithCapital |
Custom PMD XPath |
Every API name of a Flow, a custom object, or a custom field starts with a capital letter |
MethodNamingConventions |
Stock PMD |
Method names are in camel case; underscores are allowed |
MethodWithSameNameAsEnclosingClass |
Stock PMD |
Only a constructor has the name of its class |
MinVersionForAbstractVirtualClassesWithPrivateMethod |
Stock Code Analyzer Regex |
An abstract or virtual class with a private method is at API 61.0 or later |
MissingDescription |
Stock Code Analyzer Flow |
A Flow, and every element, variable, and resource in it, carries a description |
MissingFaultHandler |
Stock Code Analyzer Flow |
Every Flow element that can fail has a fault path |
MissingNextValueConnector |
Stock Code Analyzer Flow |
A Loop element has a next value connector |
MissingNullCheckOnSoqlVariable |
Stock Code Analyzer SFGE |
Check a variable used in a WHERE clause for null first |
MissingStaticMethodInNonInstantiatableClassApex |
Custom PMD XPath |
A class with only private constructors has a public static member |
MisuseOfAssertClass |
Custom PMD XPath |
No assertion fixed by a string, a number, or a new instance written into it |
ModifyOrViewAllData |
Custom PMD XPath |
No profile or permission set grants ViewAllData or ModifyAllData |
ModifyOrViewAllRecordsCustom |
Custom PMD XPath |
No profile or permission set grants View All or Modify All Records on a custom object |
ModifyOrViewAllRecordsStandard |
Custom PMD XPath |
No profile or permission set grants View All or Modify All Records on a standard object |
MouseEventWithoutKeyboardEventHtml |
Custom PMD XPath |
Every function that a mouse reaches, a keyboard reaches too |
MouseEventWithoutKeyboardEventVf |
Custom PMD XPath |
Every function that a mouse reaches in a Visualforce page, a keyboard reaches too |
MultipleTriggersOnObject |
Custom PMD Java |
Each object has at most one trigger |
NcssCount |
Stock PMD |
A method has at most 40 statements, and a class at most 500 |
NestedScriptElement |
Custom PMD XPath |
A script block does not hold the text of another script tag |
no-cond-assign |
Stock Code Analyzer ESLint |
No assignment in a condition |
no-console |
Stock Code Analyzer ESLint |
No console statements |
no-debugger |
Stock Code Analyzer ESLint |
No debugger statements |
no-else-return |
Stock Code Analyzer ESLint |
No else after an if block that ends in return |
no-extend-native |
Stock Code Analyzer ESLint |
No property is added to a built-in JavaScript object |
no-global-assign |
Stock Code Analyzer ESLint |
Nothing is assigned to a read-only global |
no-implicit-globals |
Stock Code Analyzer ESLint |
No top-level declaration becomes a global |
no-implied-eval |
Stock Code Analyzer ESLint |
setTimeout and setInterval take a function, never a string of code |
no-lone-blocks |
Stock Code Analyzer ESLint |
No block that belongs to no statement and declares nothing |
no-param-reassign |
Stock Code Analyzer ESLint |
A function does not change a property of an argument it receives |
no-restricted-syntax |
Stock Code Analyzer ESLint |
No variable, parameter, function, class, or import named top or location |
no-script-url |
Stock Code Analyzer ESLint |
No javascript: URL is written in JavaScript |
no-shadow-restricted-names |
Stock Code Analyzer ESLint |
No variable named undefined, NaN, Infinity, arguments, or eval |
no-undef |
Stock Code Analyzer ESLint |
Every variable is declared, with const, let, or var |
no-unreachable |
Stock Code Analyzer ESLint |
No statement follows a return, throw, break, or continue in the same block |
no-with |
Stock Code Analyzer ESLint |
No with statement |
NoColonAfterApexDocTag |
Custom PMD XPath |
No colon between an ApexDoc tag and its text |
NoConsecutiveBlankLines |
Custom Code Analyzer Regex |
At most one blank line in a row |
NoConsoleInVisualforce |
Custom Code Analyzer Regex |
No console statement in a Visualforce page or component |
NoCredentialNamedField |
Custom PMD Java |
No credential is kept in a field; keep it in an External Credential |
NoElseReturn |
Stock PMD |
No else after an if block that ends in return |
NoEmptyBlockComments |
Custom Code Analyzer Regex |
No empty block comment |
NoHardcodedWeblinkURLs |
Custom PMD XPath |
A web link does not hold the absolute URL of a Salesforce org |
NoInlineEventHandlerAura |
Custom PMD XPath |
An event attribute in Aura markup names a controller action, not a script |
NoLastModifiedApexDocTag |
Custom PMD XPath |
No @last modified tag, such as @last modified on, in an ApexDoc comment |
NoLightningOutApplicationAura |
Custom PMD XPath |
An Aura application should not be a Lightning Out (beta) dependency app |
NoLightningOutInVisualforce |
Custom PMD XPath |
A Visualforce page or component should not use Lightning Out (beta) |
NoListCustomSetting |
Custom PMD XPath |
No new list custom setting; use a custom metadata type |
NoMethodsInTriggers |
Custom PMD XPath |
A trigger declares no methods |
NonPrivateCustomObjectSharing |
Custom PMD XPath |
A custom object's internal and external org-wide defaults are Private, or controlled by the platform |
NonPrivateStandardObjectSharing |
Custom PMD XPath |
A standard object's internal and external org-wide defaults are Private, or controlled by the platform |
NonUnitTestContainsAsserts |
Custom PMD XPath |
Assertions only in test code |
NoPolyfillIo |
Custom Code Analyzer Regex |
Nothing loads from polyfill.io |
NoSecurityEnforced |
Custom PMD XPath |
Do not use WITH SECURITY_ENFORCED; use WITH USER_MODE |
NoSfdocDefaultAuthor |
Custom Code Analyzer Regex |
The author is a person or a team, never a tool default such as ChangeMeIn@UserSettingsUnder.SFDoc |
NoSingleLetterVariableName |
Custom PMD XPath |
No one-letter variable names, except i and j as loop counters and e in a catch block |
NoTrailingWhitespace |
Stock Code Analyzer Regex |
No line ends in a space or a tab, and no line is only whitespace |
NoUnapprovedEslintSuppression |
Custom Code Analyzer Regex |
No ESLint suppression without an approving review from the owning team |
NoUnapprovedSuppression |
Custom Code Analyzer Regex |
No PMD or Code Analyzer suppression without an approving review from the owning team |
NoUnnecessaryReturnVariables |
Custom PMD XPath |
Return a value directly: return calculate();, not a variable that is set and then only returned |
NoUnresolvedTodosApex |
Custom Code Analyzer Regex |
No TODO, TO-DO, FIXME, FIX-ME, or HACK comment stays in Apex |
NoUnresolvedTodosJavaScript |
Custom Code Analyzer Regex |
No TODO, TO-DO, FIXME, FIX-ME, or HACK comment stays in JavaScript |
NoUnresolvedTodosMarkup |
Custom Code Analyzer Regex |
No TODO, TO-DO, FIXME, FIX-ME, or HACK stays in a markup comment |
ObjectWithoutAlternativeHtml |
Custom PMD XPath |
An object element holds fallback content |
ObjectWithoutAlternativeVf |
Custom PMD XPath |
An object element in a Visualforce page holds fallback content |
ObsoleteFlow |
Custom PMD XPath |
A Flow that has been deactivated is removed from the repository |
OneDeclarationPerLine |
Stock PMD |
Declare each variable on its own line |
OperationWithHighCostInLoop |
Stock PMD |
Make an expensive call, such as Schema.describeSObjects(), once before a loop, never inside it |
OperationWithLimitsInLoop |
Stock PMD |
No SOQL, SOSL, DML, Database method, email send, or asynchronous call inside a loop |
OverrideBothEqualsAndHashcode |
Stock PMD |
A class that overrides equals(Object) also overrides hashCode(), and the reverse |
PositionLiteralsFirstInComparisons |
Custom PMD XPath |
Call equals on the string literal, not on the variable |
PreferNullCoalescingOverTernary |
Custom PMD XPath |
Use the null coalescing operator for a default: name ?? 'none' |
PreferSafeNavigationOperator |
Custom PMD XPath |
Use the safe navigation operator for one call on an object that may be null: account?.close() |
PreferSwitchOverIfElseChains |
Custom PMD XPath |
Use switch, not an if / else if chain, for a string, an integer, an enum, or an sObject type |
PreventPassingUserDataIntoElementWithoutSharing |
Stock Code Analyzer Flow |
A Flow in system context without sharing never lets user-entered data choose the records it reads or writes |
PreventPassingUserDataIntoElementWithSharing |
Stock Code Analyzer Flow |
A Flow in system context with sharing never lets user-entered data choose the records it reads or writes |
ProhibitedMetadataType |
Custom PMD XPath |
No metadata file of a Tier 0 type is committed to version control |
PropertyNamingConventions |
Stock PMD |
Property names are in camel case |
ProtectSensitiveData |
Stock Code Analyzer PMD |
No credential is kept in a field of a custom object, a custom metadata type, or a custom setting |
QueueableWithoutFinalizer |
Stock PMD |
A Queueable job whose failure needs a recovery action attaches a finalizer |
radix |
Stock Code Analyzer ESLint |
parseInt is always given a radix, as in parseInt(value, 10) |
Redundant Soql |
Stock Code Analyzer ApexGuru |
Do not run the same query twice in a transaction; keep the result in a map |
RefactorAssert |
Custom PMD XPath |
Assertions use the Assert class, not System.assert |
RegexPatternsMustBeStaticFinal |
Custom PMD XPath |
Compile a regular expression that runs more than once as a static final Pattern |
RepeatedLandmarkWithoutUniqueLabelHtml |
Custom PMD XPath |
Landmarks with the same role have different labels |
RepeatedLandmarkWithoutUniqueLabelVf |
Custom PMD XPath |
Landmarks with the same role in a Visualforce page have different labels |
RequireAccessMode |
Custom PMD Java |
Every database operation states its access mode: inline SOQL and SOSL, Database and Search methods, and DML |
RequireExplicitSharing |
Custom PMD XPath |
Every outer class declares its sharing, a test class included: with sharing by default, inherited sharing for a utility class |
RequireInnerClassSharing |
Custom PMD XPath |
An inner class should declare its sharing too |
RequireInvocableNoArgConstructor |
Custom PMD Java |
A class with an @InvocableVariable member and an explicit constructor also has a visible no-argument constructor at API 66.0 and later |
RequireLazyLoadingInGetters |
Custom PMD XPath |
A getter that queries loads its value lazily |
RequireOuterClassAccess |
Custom PMD XPath |
Every outer class declares its access modifier |
RequireSecureCookie |
Custom PMD XPath |
A cookie that JavaScript sets has the Secure attribute |
RequireTestForOrCritical |
Custom PMD XPath |
Every test class carries testFor, naming the classes and triggers it tests, or critical=true |
ReturnEmptyArrayRatherThanNull |
Custom PMD XPath |
Return an empty collection, not null |
SameRecordUpdate |
Stock Code Analyzer Flow |
A record-triggered Flow changes its own record before the save, not after it |
ScheduledFlowMinimumApiVersion |
Custom PMD XPath |
A schedule-triggered Flow runs on API version 61.0 or later |
SchemaGetGlobalDescribeNotEfficient |
Stock Code Analyzer ApexGuru |
Avoid Schema.getGlobalDescribe(); describe only the objects needed |
ScreenFlowTextRecordId |
Custom PMD XPath |
A screen Flow launched from a record declares recordId as a record variable of the object |
ServerSideImageMapHtml |
Custom PMD XPath |
No image is a server-side image map |
ServerSideImageMapVf |
Custom PMD XPath |
No image in a Visualforce page is a server-side image map |
SimplifiedTernaryApex |
Custom PMD XPath |
No ternary expression with true or false as a result |
SimplifyBooleanReturnsApex |
Custom PMD XPath |
Return a condition directly, not through an if that returns true or false |
SimplifyConditionalApex |
Custom PMD XPath |
No null check next to instanceof |
SObjectMapInAForLoop |
Stock Code Analyzer ApexGuru |
Build a map of records by Id with the map constructor or putAll(), not put in a loop |
Soql Aggregation |
Stock Code Analyzer ApexGuru |
Use an aggregate query (COUNT(), SUM()) for counts and totals, not a loop |
SoqlInALoop |
Stock Code Analyzer ApexGuru |
No SOQL query inside a loop |
SoqlInALoopOneHop |
Stock Code Analyzer ApexGuru |
No SOQL query in a method that a loop calls |
SoqlWithApexFilter |
Stock Code Analyzer ApexGuru |
Filter records in the WHERE clause, not in Apex after the query |
SoqlWithNegativeExpressions |
Stock Code Analyzer ApexGuru |
No NOT IN or != in a WHERE clause; they cannot use an index |
SoqlWithoutAWhereClauseOrLimitStatement |
Stock Code Analyzer ApexGuru |
Every SOQL query has a WHERE clause or a LIMIT |
SoqlWithoutPlatformCache |
Stock Code Analyzer ApexGuru |
Serve a query that runs often, on data that rarely changes, from Platform Cache |
SoqlWithUnusedFields |
Stock Code Analyzer ApexGuru |
Select only the fields the code reads |
SoqlWithWildcardFilter |
Stock Code Analyzer ApexGuru |
No LIKE filter that starts with a wildcard; it cannot use an index |
SortingInApex |
Stock Code Analyzer ApexGuru |
Sort records with ORDER BY, not in Apex after the query |
StatementsShouldBeOnSeparateLines |
Custom PMD XPath |
Each statement on its own line |
SwitchWithoutWhenElse |
Custom PMD XPath |
Every switch has a when else block |
symbol-description |
Stock Code Analyzer ESLint |
A Symbol is created with a description, as in Symbol('rowId') |
TableCellHeaderNotFoundHtml |
Custom PMD XPath |
A headers attribute names only the id of a th in the same table |
TableCellHeaderNotFoundVf |
Custom PMD XPath |
A headers attribute in a Visualforce page names only the id of a th in the same table |
TableHeaderWithoutScopeHtml |
Custom PMD XPath |
A header cell has a scope, or an id that cells name in their headers attribute |
TableHeaderWithoutScopeVf |
Custom PMD XPath |
A header cell in a Visualforce page has a scope, or an id that cells name in their headers attribute |
TableWithoutCaptionHtml |
Custom PMD XPath |
A data table says what it holds, in a caption or an ARIA label |
TableWithoutCaptionVf |
Custom PMD XPath |
A data table in a Visualforce page says what it holds, in a caption or an ARIA label |
TableWithoutHeadersHtml |
Custom PMD XPath |
A data table marks its header cells with th |
TableWithoutHeadersVf |
Custom PMD XPath |
A data table in a Visualforce page marks its header cells with th |
TestClassIsParallel |
Custom PMD XPath |
A test class states IsParallel=true or IsParallel=false |
TestClassWithoutTestCasesApex |
Custom PMD XPath |
Every test class has a test method, except a test helper |
TestMethodsMustBeInTestClasses |
Stock PMD |
Every test method is in a class that carries @IsTest |
TooManyFields |
Stock PMD |
Split a class with too many fields; related fields belong in a type of their own |
TriggerCallout |
Stock Code Analyzer Flow |
A record-triggered Flow makes no callout on its synchronous path |
TriggerEntryCriteria |
Stock Code Analyzer Flow |
A record-triggered Flow has entry conditions in its trigger definition |
TriggerNameSuffix |
Custom PMD XPath |
A trigger name ends in Trigger, or in the one suffix the organisation sets |
TriggerWaitEvent |
Stock Code Analyzer Flow |
A record-triggered Flow reaches no Wait element on its synchronous path |
TypeShadowsBuiltInNamespace |
Stock PMD |
No class, enum, or interface takes the name of a System or Schema type |
UnconditionalIfStatementApex |
Custom PMD XPath |
No if condition that is always true or always false |
UnimplementedType |
Stock Code Analyzer SFGE |
An abstract class or an interface that is not global has at least one implementation |
UnitTestsShouldIncludeStartTest |
Custom PMD XPath |
A test method calls Test.startTest() and Test.stopTest() |
UnnecessaryBooleanAssertionApex |
Custom PMD XPath |
No assertion fixed by true, false, or null written into it |
UnnecessaryParentheses |
Stock PMD |
No redundant parentheses around an expression |
UnreachableCode |
Stock PMD |
No statement follows a return, throw, break, or continue in the same block |
UnreachableElement |
Stock Code Analyzer Flow |
Every Flow element is connected to the start element |
UnusedLocalVariable |
Stock PMD |
Remove a local variable that is never read |
UnusedMethod |
Stock PMD |
Remove a method that is never called |
UnusedNullCheckInEqualsApex |
Custom PMD XPath |
A null check before equals checks the object whose method is called |
UnusedResource |
Stock Code Analyzer Flow |
A Flow has no variable that it does not use |
UseAreEqualInsteadOfAssertBoolean |
Custom PMD XPath |
Compare two values with Assert.areEqual, not == in Assert.isTrue |
UseAreEqualInsteadOfIsTrue |
Custom PMD XPath |
Compare two values with Assert.areEqual, not equals() in Assert.isTrue |
UseBaseWithParseInt |
Stock PMD |
parseInt is always given a radix, as in parseInt(value, 10) |
UseCollectionIsEmptyApex |
Custom PMD XPath |
Test for an empty collection with isEmpty() |
UseIsTrueInsteadOfAreEqual |
Custom PMD XPath |
Check a Boolean with Assert.isTrue or Assert.isFalse, not Assert.areEqual |
UsingTheTestMethodKeyword |
Stock Code Analyzer ApexGuru |
No testMethod keyword; mark a test method with @IsTest |
VfCsrf |
Stock PMD |
A page changes no data when it loads; the action of apex:page calls no method that writes |
VfHtmlStyleTagXss |
Stock PMD |
A merge expression in a style element is encoded |
VfUnescapeEl |
Stock PMD |
A merge expression is always encoded for the place it is written |
VideoWithoutCaptionsHtml |
Custom PMD XPath |
A video has a track of captions or subtitles |
VideoWithoutCaptionsVf |
Custom PMD XPath |
A video in a Visualforce page has a track of captions or subtitles |
ViewSetupPermissionSet |
Custom PMD XPath |
No permission set grants ViewSetup |
ViewSetupProfile |
Custom PMD XPath |
No custom profile grants ViewSetup |
VisualforceControllerNaming |
Custom PMD XPath |
A custom controller's name ends in Controller, and a controller extension's in Extension or Ext |
VisualforceHeaderComment |
Custom Code Analyzer Regex |
A Visualforce page or component starts with a comment that says what it is for |
WhileLoopsMustUseBraces |
Stock PMD |
Wrap the body of every while loop in braces, even one line |
WritingFillerStatements |
Stock Code Analyzer ApexGuru |
Never pad coverage with filler statements |