dotnet/machinelearning · error · ArgumentException
This is not a causal mask
Error message
This is not a causal mask
What it means
AttentionMaskConverter.ToCausal4D throws ArgumentException when asked to build a 4D causal mask while the converter's _isCausal flag is false. ToCausal4D is the fallback path used when no 2D attention mask is supplied, and it only makes sense for causal attention.
Solutions
- Construct the AttentionMaskConverter with isCausal: true for decoder/causal models.
- Pass an explicit 2D attention mask so the To4D path is used instead.
- Verify the model config's is_causal/decoder flag matches the converter flags.
- For encoder-style models, don't call ToCausal4D — expand the 2D mask with ExpandMask instead.
Example fix
// before var converter = new AttentionMaskConverter(isCausal: false); var mask4d = converter.ToCausal4D(batchSize, qLen, kvLen, dType, device); // after var converter = new AttentionMaskConverter(isCausal: true); var mask4d = converter.ToCausal4D(batchSize, qLen, kvLen, dType, device);
Defensive patterns
Strategy: validation
Validate before calling
if (!isCausal) throw new InvalidOperationException("ToCausal4D requires isCausal: true converter"); Type guard
bool CausalOk(bool isCausal) => isCausal;
Try / catch
try { var mask = converter.ToCausal4D(batch, qLen, kvLen, dType, device); }
catch (ArgumentException ex) when (ex.Message.Contains("not a causal mask")) { logger.LogError("Converter constructed with isCausal=false; use To4D/ExpandMask instead"); throw; } Prevention
- Set isCausal: true for all decoder (causal LM) models.
- Use To4D/ExpandMask paths for encoder-style non-causal masks.
- Align converter flags with the model config's decoder flag.
- Don't reuse a bidirectional converter instance in generation code.
When it happens
Trigger: Calling Create4DCausalAttentionMask with attentionMask == null on a converter constructed with isCausal: false.
Common situations: Reusing a bidirectional (non-causal) mask converter in a decoder model where no explicit 2D mask is provided; copy-pasted converter setup from an encoder model into a causal LM pipeline.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Attention mask should be 2D
- key_value_length should be provided when attention_mask is…
- Sliding window is not supported for non-causal masks
- Array lengths are mistmached
- Blob for normalization rule is broken.
AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11).
Data as JSON: /api/errors/dacc67041218dc89.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.ML.GenAI.Core/Utility/AttentionMaskConverter.cs:80
if (causal4dMask is not null)
{
var min = torch.finfo(dType).min;
expandedAttnMask = causal4dMask.masked_fill(expandedAttnMask.to(ScalarType.Bool), min);
}
return expandedAttnMask;
}
public Tensor? ToCausal4D(
int batchSize,
int queryLength,
int keyValueLength,
ScalarType dType,
Device device)
{
if (!_isCausal)
{
throw new ArgumentException("This is not a causal mask");
}
long[] inputShape = [batchSize, queryLength];
var pastKeyValueLength = keyValueLength - queryLength;
// create causal mask
// [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len]
Tensor? causal4DMask = null;
if (queryLength > 1 || this._slidingWindow is int)
{
causal4DMask = MakeCausalMask(inputShape, dType, device, pastKeyValueLength, this._slidingWindow);
}
return causal4DMask;
}
public static Tensor MakeCausalMask(
long[] inputIdsShape,View on GitHub (pinned to 7b76e69cf9)