Bicep diagnostic code - BCP318

This diagnostic occurs when you try to access a property on a value that may or may not be null. The diagnostic will also be raised when attempting to access a property on a conditional resource (that is, a resource declared with an if clause in Bicep). References to resources with a false condition will generally cause the deployment to fail with a validation error.

Description

The value of type "<resource-type> | null" may be null at the start of the deployment, which would cause this access expression (and the overall deployment with it) to fail.

Level

Warning

Solutions

If the value might be null and your template can safely handle null for the entire expression, use the safe-dereference operator. This short-circuits the access if the base expression is null or a resource whose condition is false.

If you're certain the value will never be null, use the null-forgiving operator to tell the compiler it's safe. This will disable compile-time validation, but runtime validation will still be performed.

Examples

The following example raises the diagnostic because Bicep can't guarantee that accounts[i] exists for every i in range(0, storageCount). Some indices are skipped, so direct indexing is unsafe.

param storageCount int

resource accounts 'Microsoft.Storage/storageAccounts@2015-01-01' = [for i in range(0, storageCount): if (i % 2 == 0) {
  name: 'sa${i}'
  location: resourceGroup().location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
}]

output storageEndpoints array = [for i in range(0, storageCount): accounts[i].properties.primaryEndpoints.blob]

You can fix the diagnostic by using the safe-dereference operator:

param storageCount int

resource accounts 'Microsoft.Storage/storageAccounts@2015-01-01' = [for i in range(0, storageCount): if (i % 2 == 0) {
  name: 'sa${i}'
  location: resourceGroup().location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
}]

output storageEndpoints array = [for i in range(0, storageCount): accounts[i].?properties.primaryEndpoints.blob]

The following example raises the diagnostic because the if condition makes the array length indeterminate at compile time, so Bicep can't safely allow direct indexing like accounts[0].

param storageCount int = 2

resource accounts 'Microsoft.Storage/storageAccounts@2015-01-01' = [for i in range(0, storageCount): if (i % 2 == 0) {
  name: 'sa${i}'
  location: resourceGroup().location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
}]

output firstOne object = accounts[0].properties

You can fix the diagnostic by using the null-forgiving operator:

param storageCount int = 2

resource accounts 'Microsoft.Storage/storageAccounts@2015-01-01' = [for i in range(0, storageCount): if (i % 2 == 0) {
  name: 'sa${i}'
  location: resourceGroup().location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
}]

output firstOne object = accounts[0]!.properties

Next steps

For more information about Bicep diagnostics, see Bicep core diagnostics.