Have you tried to resolve this issue yourself first?
Bug Description
Engine: sfge (Salesforce Graph Engine) · Rule: ApexFlsViolation (DevPreview) · Selector: --rule-selector sfge
A cast or an array load used as a value inside a new SObject(Field = ...) constructor aborts path evaluation. Both are the same underlying contract problem in SFVertexFactory.
NewKeyValueObjectExpressionVertex loads its item vertices with a supplemental parameter (NewKeyValueObjectExpressionVertex.java:57-65 passes ExpressionType.KEY_VALUE). SFVertexFactory.load then requires a two-argument constructor:
// SFVertexFactory.java:231-238
if (supplementalParam != null) {
Constructor constructor = optClazz.get().getDeclaredConstructor(Map.class, Object.class);
result = (T) constructor.newInstance(vertexProperties, supplementalParam);
}
getDeclaredConstructor does not search superclasses.
A. Cast. CastExpressionVertex declares only (Map), so the lookup throws NoSuchMethodException, rewrapped as UnexpectedException at SFVertexFactory.java:245.
Account a = new Account(Name = (String) rawName);
B. Array load. ArrayLoadExpressionVertex has the two-argument constructor but rejects the supplemental parameter outright:
// ArrayLoadExpressionVertex.java:34-38
ArrayLoadExpressionVertex(Map<Object, Object> properties, Object supplementalParam) {
super(properties, TRAVERSAL_CONSUMER);
if (supplementalParam != null) {
throw new UnexpectedException(supplementalParam);
}
}
Since ChainedVertex(Map, Object) discards the supplemental parameter anyway — its own constructor is annotated // TODO: supplementalParam is ignored — there is nothing for that branch to protect. Note the user-visible message for B is null; the informative KEY_VALUE payload only reaches the sfge log.
Output / Logs
# A — cast as a key-value item
UnexpectedException: com.salesforce.graph.vertex.CastExpressionVertex.<init>(java.util.Map, java.lang.Object):
com.salesforce.graph.vertex.SFVertexFactory.load(SFVertexFactory.java:245);
com.salesforce.graph.vertex.SFVertexFactory$1.apply(SFVertexFactory.java:186);
com.salesforce.graph.cache.AbstractVertexCacheImpl.get(AbstractVertexCacheImpl.java:101);
com.salesforce.graph.vertex.LazyVertexList.initialize(LazyVertexList.java:47)
# B — array load as a key-value item (violation message is just "null")
UnexpectedException: null: com.salesforce.graph.vertex.SFVertexFactory.load(SFVertexFactory.java:245); ...
Caused by: com.salesforce.exception.UnexpectedException: KEY_VALUE
at com.salesforce.graph.vertex.ArrayLoadExpressionVertex.<init>(ArrayLoadExpressionVertex.java:37)
Steps To Reproduce
-
Create an empty SFDX project (sfdx-project.json with a single force-app package directory).
-
Add both classes under force-app/main/default/classes/, each with a standard .cls-meta.xml (apiVersion 62.0):
public with sharing class CastInKeyValue {
@AuraEnabled
public static void run(Object rawName) {
Account a = new Account(Name = (String) rawName);
insert a;
}
}
public with sharing class ArrayLoadInKeyValue {
private static final List<String> PARTS = String.valueOf(ArrayLoadInKeyValue.class).split('[.]', 2);
@AuraEnabled
public static void run() {
insert new Account(Name = PARTS[0]);
}
}
-
Add code-analyzer.yml:
engines:
sfge:
java_thread_timeout: 900000
java_thread_count: 4
-
Run sf code-analyzer run --rule-selector sfge --workspace . --config-file code-analyzer.yml.
-
Both classes report an InternalExecutionError and yield no findings for their entry point.
Expected Behavior
Both should analyse normally. new Account(Name = (String) x) and new Account(Name = list[0]) are ordinary Apex.
The narrow fix for A is one constructor, mirroring the eleven vertex classes that already have it (BinaryExpressionVertex, BooleanExpressionVertex, MethodCallExpressionVertex, …). Since ChainedVertex(Map, Object) ignores the parameter, it is a pure delegation. The fix for B is to drop the throw on that branch.
A more durable fix would be for SFVertexFactory.load to fall back to the one-argument constructor when the two-argument form is absent, rather than requiring every vertex type to opt in.
Operating System
macOS 26.5.2
Salesforce CLI Version
@salesforce/cli/2.147.7 darwin-arm64 node-v24.5.0
Code Analyzer Plugin (code-analyzer) Version
code-analyzer 5.15.0
Node Version
v24.5.0
Java Version
openjdk version "11.0.32" 2026-07-21
Python Version
N/A
Additional Context (Screenshots, Files, etc)
Blast radius. CastExpression and ArrayLoadExpression are not the only vertices that can appear as a key-value item. Auditing graph/vertex/ on code-analyzer-core@dev, 15 other concrete ChainedVertex descendants also lack the two-argument constructor (and have no Builder.create(Map, Object) to stand in), so they should fail the same way: AssignmentExpressionVertex, BindExpressionsVertex, ClassRefExpressionVertex, EmptyReferenceExpressionVertex, InstanceOfExpressionVertex, MapEntryNodeVertex, NewKeyValueObjectExpressionVertex, NewObjectExpressionVertex, ParameterVertex, PostfixExpressionVertex, ReferenceExpressionVertex, SoqlExpressionVertex, SuperMethodCallExpressionVertex, ThisMethodCallExpressionVertex, TriggerVariableExpressionVertex.
Related: #886 reported a CastExpressionVertex UnexpectedException in 2022 from a different path (MethodPathBuilderVisitor on switch on (String) x); #973 reported the array-load half. Both were closed in the 2026-06-30 pre-v5 sweep; this is a different call path on 5.15.0.
Workaround
Hoist the expression into a local first:
String name = (String) rawName;
Account a = new Account(Name = name);
Works, but it means the constructor-initialiser syntax cannot be used with a cast or an index anywhere in the codebase.
Urgency
Moderate
Have you tried to resolve this issue yourself first?
Bug Description
Engine:
sfge(Salesforce Graph Engine) · Rule:ApexFlsViolation(DevPreview) · Selector:--rule-selector sfgeA cast or an array load used as a value inside a
new SObject(Field = ...)constructor aborts path evaluation. Both are the same underlying contract problem inSFVertexFactory.NewKeyValueObjectExpressionVertexloads its item vertices with a supplemental parameter (NewKeyValueObjectExpressionVertex.java:57-65passesExpressionType.KEY_VALUE).SFVertexFactory.loadthen requires a two-argument constructor:getDeclaredConstructordoes not search superclasses.A. Cast.
CastExpressionVertexdeclares only(Map), so the lookup throwsNoSuchMethodException, rewrapped asUnexpectedExceptionatSFVertexFactory.java:245.B. Array load.
ArrayLoadExpressionVertexhas the two-argument constructor but rejects the supplemental parameter outright:Since
ChainedVertex(Map, Object)discards the supplemental parameter anyway — its own constructor is annotated// TODO: supplementalParam is ignored— there is nothing for that branch to protect. Note the user-visible message for B isnull; the informativeKEY_VALUEpayload only reaches the sfge log.Output / Logs
Steps To Reproduce
Create an empty SFDX project (
sfdx-project.jsonwith a singleforce-apppackage directory).Add both classes under
force-app/main/default/classes/, each with a standard.cls-meta.xml(apiVersion 62.0):Add
code-analyzer.yml:Run
sf code-analyzer run --rule-selector sfge --workspace . --config-file code-analyzer.yml.Both classes report an
InternalExecutionErrorand yield no findings for their entry point.Expected Behavior
Both should analyse normally.
new Account(Name = (String) x)andnew Account(Name = list[0])are ordinary Apex.The narrow fix for A is one constructor, mirroring the eleven vertex classes that already have it (
BinaryExpressionVertex,BooleanExpressionVertex,MethodCallExpressionVertex, …). SinceChainedVertex(Map, Object)ignores the parameter, it is a pure delegation. The fix for B is to drop thethrowon that branch.A more durable fix would be for
SFVertexFactory.loadto fall back to the one-argument constructor when the two-argument form is absent, rather than requiring every vertex type to opt in.Operating System
macOS 26.5.2
Salesforce CLI Version
@salesforce/cli/2.147.7 darwin-arm64 node-v24.5.0
Code Analyzer Plugin (code-analyzer) Version
code-analyzer 5.15.0
Node Version
v24.5.0
Java Version
openjdk version "11.0.32" 2026-07-21
Python Version
N/A
Additional Context (Screenshots, Files, etc)
Blast radius.
CastExpressionandArrayLoadExpressionare not the only vertices that can appear as a key-value item. Auditinggraph/vertex/oncode-analyzer-core@dev, 15 other concreteChainedVertexdescendants also lack the two-argument constructor (and have noBuilder.create(Map, Object)to stand in), so they should fail the same way:AssignmentExpressionVertex,BindExpressionsVertex,ClassRefExpressionVertex,EmptyReferenceExpressionVertex,InstanceOfExpressionVertex,MapEntryNodeVertex,NewKeyValueObjectExpressionVertex,NewObjectExpressionVertex,ParameterVertex,PostfixExpressionVertex,ReferenceExpressionVertex,SoqlExpressionVertex,SuperMethodCallExpressionVertex,ThisMethodCallExpressionVertex,TriggerVariableExpressionVertex.Related: #886 reported a
CastExpressionVertexUnexpectedExceptionin 2022 from a different path (MethodPathBuilderVisitoronswitch on (String) x); #973 reported the array-load half. Both were closed in the 2026-06-30 pre-v5 sweep; this is a different call path on 5.15.0.Workaround
Hoist the expression into a local first:
Works, but it means the constructor-initialiser syntax cannot be used with a cast or an index anywhere in the codebase.
Urgency
Moderate