DFX4xxx — Values, types and expressions
Every DFX4xxx diagnostic, with its severity, verbatim message, cause and fix.
32 codes in this family (32 error). The message is the format string as the compiler holds it: %s, %d and %c are substituted at runtime.
DFX4001
errorraised byGeneration/DreamFXValueLowering.cpp:520Generation/DreamFXValueLowering.cpp:530Generation/DreamFXValueLowering.cpp:545Generation/DreamFXValueLowering.cpp:621
Input '%s' expects %s, but a number was written.
Cause. A bare number was written where the input wants a vector, colour or other structured type.
Fix. Write all the components: (0, 0, -980).
DFX4002
errorraised byGeneration/DreamFXExpressions.cpp:119Generation/DreamFXGenerator.cpp:331Generation/DreamFXValueLowering.cpp:444Generation/DreamFXValueLowering.cpp:514Generation/DreamFXValueLowering.cpp:553
Expression for '%s': a vector literal must have 2 to 4 components.
Cause. Niagara vector types are 2, 3 or 4 components.
Fix. Check the component count.
DFX4003
errorraised byGeneration/DreamFXValueLowering.cpp:501
Input '%s' is an integer, but %s was written. Narrowing is not implicit -- write int(%s) if truncation is intended.
Cause. L7: float -> int is never implicit. A silently truncated spawn count is among the hardest effect bugs to find.
Fix. Write int(...) if truncation is what you meant, or make the source an int.
DFX4004
errorraised byGeneration/DreamFXValueLowering.cpp:463Generation/DreamFXValueLowering.cpp:580
Input '%s' has no resolvable Niagara type.
Cause. The input's type could not be resolved from the module schema.
Fix. Usually the input is hidden behind a static switch that has not been written yet -- write the switch first; source order is write order.
DFX4005
errorraised byGeneration/DreamFXGenerator.cpp:1122Generation/DreamFXGenerator.cpp:1443Generation/DreamFXGenerator.cpp:345Generation/DreamFXGenerator.cpp:372Generation/DreamFXValueLowering.cpp:567Generation/DreamFXValueLowering.cpp:669
Property '%s': component %d is not a number.
Cause. A vector or box() component is not a number.
Fix. Components are literals; a parameter reference cannot appear inside one.
DFX4006
errorraised byGeneration/DreamFXValueLowering.cpp:643
Input '%s' is a %s, which has no entry named '%s'. Valid entries: %s
Cause. The enum has no entry by that name. Niagara's user-defined enums store NewEnumerator0 internally and keep the real name in display text, so the names here are not guessable from the asset -- they are read live.
Fix. Use one of the entries listed. Spaces and hyphens are normalised away, so Direct Set is written DirectSet.
DFX4007
errorraised byGeneration/DreamFXValueLowering.cpp:652
Input '%s' expects %s. '%s' is neither a literal of that type nor a parameter reference -- parameter references start with a namespace such as User., Particles., Emitter., System. or Engine.
Cause. The value is neither a literal of the expected type nor a namespace-qualified parameter.
Fix. Qualify the parameter (User.Speed, Particles.Velocity), or write a literal.
DFX4010
errorraised byGeneration/DreamFXGenerator.cpp:1032Generation/DreamFXGenerator.cpp:1433
Input '%s' is set more than once on dynamic input '%s'.
Cause. The same input was given twice on one dynamic input call.
Fix. Delete one.
DFX4020
errorraised byGeneration/DreamFXValueLowering.cpp:328Generation/DreamFXValueLowering.cpp:373
Parameter '%s': 'Object' needs an inner type, e.g. Object<Texture>.
Cause. DI names no class on its own.
Fix. Write the inner type: DI<SkeletalMesh>.
DFX4021
errorraised byGeneration/DreamFXValueLowering.cpp:361Generation/DreamFXValueLowering.cpp:407
Parameter '%s': no UObject class named '%s'. Object<> takes a class name such as Object<Texture> or Object<StaticMesh>.
Cause. The declared type is not one DreamFX knows.
Fix. Use one of the types listed in the message.
DFX4022
errorraised byGeneration/DreamFXValueLowering.cpp:451
Cannot infer the type of '%s' from its value. A first assignment to a new attribute must use a literal, so its type is unambiguous.
Cause. L2 types a new attribute from its first value, and this value carries no type -- an hlsl block, a dynamic input and an inline expression all have none of their own.
Fix. Write the type: Color Particles.Moon.Tint = hlsl { ... };
DFX4023
errorraised byGeneration/DreamFXGenerator.cpp:457Generation/DreamFXGenerator.cpp:469
Property '%s': box() takes 6 numbers -- minX, minY, minZ, maxX, maxY, maxZ.
Cause. box() is minX, minY, minZ, maxX, maxY, maxZ.
Fix. Write six numbers.
DFX4024
errorraised byGeneration/DreamFXGenerator.cpp:735
Cannot type '%s = %s': the type of '%s' is not known here. Declare it in Properties, or assign a literal first so the type is explicit.
Cause. The right-hand side references a parameter whose type is not known at this point.
Fix. Declare it in Properties, or assign it a literal earlier in the same stack -- L2's first write is what declares an attribute.
DFX4025
errorraised byGeneration/DreamFXGenerator.cpp:1113Generation/DreamFXGenerator.cpp:1938
'%s' is not a valid assignment target. Parameter names are namespace-qualified, e.g. Particles.MyValue or Emitter.MyCounter.
Cause. An unqualified assignment target has no namespace to live in, and guessing one would put the value somewhere never named.
Fix. Qualify it: Particles.MyValue, Emitter.MyValue, System.MyValue.
DFX4026
errorraised byGeneration/DreamFXGenerator.cpp:1497
'Bind %s -> %s': the target must be a qualified parameter -- either a namespace such as Particles.SpriteSize, or an emitter's own alias such as MyEmitter.Velocity.
Cause. A renderer binding target is a parameter, not a bare name.
Fix. Write Bind Color -> Particles.Color;
DFX4027
errorraised byGeneration/DreamFXGenerator.cpp:782
'%s' is %s, but '%s' is %s. Linking binds a parameter directly -- there is no conversion. Declare '%s' as %s, or drive the input another way.
Cause. L7 across a link. A linked value binds the parameter directly -- there is no conversion step to truncate or widen in -- so the two types have to match exactly.
Fix. Declare the source parameter with the target's type. This is the one L7 case that cannot be fixed with an explicit cast, because there is nowhere to put one.
DFX4028
errorraised byGeneration/DreamFXGenerator.cpp:1946
Default for '%s' needs a declared type. A default has no module signature to infer one from, so write it: `float %s = …`.
Cause. A Defaults entry was written without a type. Elsewhere the type can come from the value or from the module signature the input belongs to; a default belongs to no module and its value may be an hlsl block or a link, so there is nothing to infer from.
Fix. Write the type: float Particles.MySize = 1.0;.
DFX4029
errorraised byGeneration/DreamFXGenerator.cpp:1983
Default for '%s' must be a literal, an enum or another parameter. A dynamic input computes a value per particle, which a default cannot do.
Cause. A Defaults entry was given a dynamic input. A default is one value stored on the parameter, and a dynamic input is a graph that runs per particle -- there is nowhere to run it.
Fix. Use a literal, an enum, or a link to another parameter. If the value really has to be computed, write it as an assignment in ParticleSpawn instead, which runs.
DFX4030
errorraised byGeneration/DreamFXExpressions.cpp:340
The hlsl block for '%s' must be a single expression: no statements, no local variables, no return. Move multi-statement logic into a .dfm DynamicInput and call it here.
Cause. A stack input's hlsl block lowers to a node with one typed output pin and no body, so it cannot hold statements.
Fix. Fold it into one expression, or move the logic into a .dfm Module, whose body is emitted verbatim. This is the gap .dfm generation exists to close.
DFX4031
errorraised byGeneration/DreamFXExpressions.cpp:158
'%s' is not an allowed inline function. Allowed: %s. Anything else belongs in a .dfm dynamic input or an hlsl { } block.
Cause. L6's whitelist. Widening it is the slide into re-implementing a 13k-line expression backend, so it is deliberately short.
Fix. Use one of the listed functions, a .dfm dynamic input, or an hlsl { } block -- inside which any HLSL is allowed.
DFX4032
errorraised byGeneration/DreamFXExpressions.cpp:100
'%s' in the expression for '%s' is not a parameter. Only namespace-qualified parameters (User.X, Particles.X, Engine.X, ...) can be read from an expression.
Cause. Inline expressions see parameters, not locals. A bare name has nothing to bind to.
Fix. Qualify it, or move the expression into an hlsl { } block where locals exist.
DFX4033
errorraised byGeneration/DreamFXExpressions.cpp:166
Builtin '%s' takes positional arguments, not named ones.
Cause. An L6 builtin is positional. Named arguments read as a dynamic input call and would silently resolve to something else.
Fix. Write saturate(x), not saturate(Value = x).
DFX4034
errorraised byGeneration/DreamFXExpressions.cpp:174
Builtin '%s' takes %d argument(s), but %d were written.
Cause. Arity is the only thing separating lerp(a, b) from lerp(a, b, t).
Fix. Check the argument count.
DFX4035
errorraised byGeneration/DreamFXExpressions.cpp:205
Expression for '%s' contains a value that has no HLSL form.
Cause. Part of the expression has no HLSL form -- a curve literal or a data interface inside arithmetic, for instance.
Fix. Move that part to its own input.
DFX4036
errorraised byGeneration/DreamFXExpressions.cpp:330
The hlsl block for '%s' is empty.
Cause. An empty hlsl block lowers to an expression with no text in it.
Fix. Write the expression, or delete the block.
DFX4037
errorraised byGeneration/DreamFXExpressions.cpp:356
'%s' is %s; a curve { } literal only fits a curve data interface input.
Cause. A curve { } literal fills a curve data interface, and this input is not one.
Fix. Feed the curve to the input that takes it -- usually a dynamic input such as FloatFromCurve(FloatCurve = curve { ... }).
DFX4038
errorraised byGeneration/DreamFXExpressions.cpp:364
The curve for '%s' has no keys.
Cause. An empty curve evaluates to nothing, which reads at runtime as a value stuck at zero.
Fix. Add keys.
DFX4039
errorraised byGeneration/DreamFXExpressions.cpp:378
Unknown curve interpolation '%s'. Expected Auto, Cubic, Linear or Constant.
Cause. Curve tangents are data (plan 3.5); an unrecognised mode would fall back to Auto and drop a hand-tuned shape without saying so.
Fix. Use Auto, Cubic, Linear or Constant.
DFX4040
errorraised byGeneration/DreamFXValueLowering.cpp:601
Parameter '%s': no asset at '%s'.
Cause. An Object<T> parameter was given an asset path and nothing is at that path. Usually the asset moved or was renamed after the source was written, or the path is a content-browser display name rather than an object path.
Fix. Copy the path from the asset's right-click Copy Reference and paste it whole: Object<Texture> _Tex = "/Game/FX/T_Spark.T_Spark";. The part after the dot is the object name inside the package and is not optional.
DFX4041
errorraised byGeneration/DreamFXValueLowering.cpp:610
Parameter '%s': '%s' is a %s, which is not a %s.
Cause. The asset at that path exists but is not the class the parameter declares. Object<Texture> = ".../M_Fire" names a material, and Niagara would refuse the binding at runtime rather than at build time.
Fix. Either point at an asset of the declared class, or widen the declaration to the class you actually mean --- Object<Texture>, Object<StaticMesh>, Object<MaterialInterface> and so on match what the module's input expects.
DFX4042
errorraised byGeneration/DreamFXExpressions.cpp:388
Unknown curve tangent mode '%s'. Expected Auto, User, Break or None.
Cause. A curve key's Tangent= attribute named something that is not one of Unreal's four tangent modes. Refused rather than defaulted for the same reason as DFX4039: falling back to Auto would silently discard the tangents written beside it, and a curve whose corners have been rounded off is a different curve.
Fix. Use Auto, User, Break or None --- or leave Tangent out entirely, in which case a key with a tangent means User and a key without means Auto, which is what every source written before the attribute existed meant.
DFX4091
errorraised byGeneration/DreamFXValueLowering.cpp:663
Input '%s': dynamic inputs, hlsl blocks, curves and inline expressions are not available yet (planned for Phase 3).
Cause. A Phase 2 build met a Phase 3 value mode. Historical -- it should not appear on a current build.
Fix. Rebuild the plugin. If it persists, the source is being compiled by an old binary.