Edit

Bicep diagnostic code - BCP364

This diagnostic occurs when the @discriminator() decorator is used but the specified discriminator property isn't a required string literal on every union member type. The discriminator property must be required (not optional) and must have a string literal type (not a general string type) on all union members.

Description

The property "<discriminator-property-name>" must be a required string literal on all union member types.

Level

Error

Solutions

Ensure the discriminator property:

  • Is present and required (no ? suffix) on all union member types.
  • Is typed as a string literal (for example, 'foo'), not as a general string type.

Examples

The following example raises the diagnostic because the type property is missing entirely from FooConfig:

type FooConfig = {
  value: int
}

type BarConfig = {
  type: 'bar'
  value: bool
}

@discriminator('type')
type ServiceConfig = FooConfig | BarConfig

You can fix the diagnostic by adding the required type string literal property to all union member types:

type FooConfig = {
  type: 'foo'
  value: int
}

type BarConfig = {
  type: 'bar'
  value: bool
}

@discriminator('type')
type ServiceConfig = FooConfig | BarConfig

param config ServiceConfig

The following example raises the diagnostic because the type property is optional (marked with ?) on FooConfig:

type FooConfig = {
  type?: 'foo'
  value: int
}

type BarConfig = {
  type: 'bar'
  value: bool
}

@discriminator('type')
type ServiceConfig = FooConfig | BarConfig

You can fix the diagnostic by making the type property required on all union member types:

type FooConfig = {
  type: 'foo'
  value: int
}

type BarConfig = {
  type: 'bar'
  value: bool
}

@discriminator('type')
type ServiceConfig = FooConfig | BarConfig

param config ServiceConfig

The following example raises the diagnostic because the type property on FooConfig is typed as a general string rather than a string literal:

type FooConfig = {
  type: string
  value: int
}

type BarConfig = {
  type: 'bar'
  value: bool
}

@discriminator('type')
type ServiceConfig = FooConfig | BarConfig

You can fix the diagnostic by changing the type property to a string literal on all union member types:

type FooConfig = {
  type: 'foo'
  value: int
}

type BarConfig = {
  type: 'bar'
  value: bool
}

@discriminator('type')
type ServiceConfig = FooConfig | BarConfig

param config ServiceConfig

The following example raises the diagnostic because the type property on FooConfig is an integer literal rather than a string literal:

type FooConfig = {
  type: 1
  value: int
}

type BarConfig = {
  type: 'bar'
  value: bool
}

@discriminator('type')
type ServiceConfig = FooConfig | BarConfig

You can fix the diagnostic by changing the type property to a string literal on all union member types:

type FooConfig = {
  type: 'foo'
  value: int
}

type BarConfig = {
  type: 'bar'
  value: bool
}

@discriminator('type')
type ServiceConfig = FooConfig | BarConfig

param config ServiceConfig

The following example raises the diagnostic because the type property on FooConfig is a union of string literals rather than a single string literal:

type FooConfig = {
  type: 'foo' | 'baz'
  value: int
}

type BarConfig = {
  type: 'bar'
  value: bool
}

@discriminator('type')
type ServiceConfig = FooConfig | BarConfig

You can fix the diagnostic by assigning a single string literal to the type property on each union member type:

type FooConfig = {
  type: 'foo'
  value: int
}

type BarConfig = {
  type: 'bar'
  value: bool
}

@discriminator('type')
type ServiceConfig = FooConfig | BarConfig

param config ServiceConfig

Next steps

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