Optional module name in for-loop with custom scope, linter warning and compile error
Bicep version Bicep CLI version 0.25.3 (862708594a)
Describe the bug
When using optionalModuleNames and specifying the scope property on a module in a for loop without a module name, the linter yields the following warning:
Unique resource or deployment name is required when looping. The loop item variable "item" must be referenced in at least one of the value expressions of the following properties: "name", "scope"
To Reproduce
resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = {
name: resourceGroupName
location: location
}
module item 'modules/item.bicep' = [for i in range(0, 5): {
scope: rg
params: { ... }
}]
Compile Result
Warning BCP179: Unique resource or deployment name is required when looping. The loop item variable "item" must be referenced in at least one of the value expressions of the following properties: "name", "scope"
Unhandled exception. System.ArgumentException: Expected module syntax body to contain property 'name'
at Bicep.Core.Intermediate.ExpressionBuilder.GetModuleNameSyntax(ModuleSymbol moduleSymbol)
at Bicep.Core.Intermediate.ExpressionBuilder.TryGetReplacementContext(ModuleSymbol module, SyntaxBase indexExpression, SyntaxBase newContext)
at Bicep.Core.Intermediate.ExpressionBuilder.ToDependencyExpression(ResourceDependency dependency, SyntaxBase newContext)
at Bicep.Core.Intermediate.ExpressionBuilder.<>c__DisplayClass29_0.<ConvertModule>b__2(ResourceDependency x)
at System.Linq.Enumerable.SelectIPartitionIterator`2.LazyToArray()
at System.Linq.Enumerable.SelectIPartitionIterator`2.ToArray()
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1)
at System.Collections.Immutable.ImmutableArray.CreateRange[T](IEnumerable`1 items)
at System.Collections.Immutable.ImmutableArray.ToImmutableArray[TSource](IEnumerable`1)
at Bicep.Core.Intermediate.ExpressionBuilder.ConvertModule(ModuleDeclarationSyntax syntax)
at Bicep.Core.Intermediate.ExpressionBuilder.ConvertWithoutLowering(SyntaxBase syntax)
at Bicep.Core.Intermediate.ExpressionBuilder.<ConvertProgram>b__26_9(ModuleSymbol x)
at System.Linq.Enumerable.SelectArrayIterator`2.MoveNext()
at System.Linq.Enumerable.OfTypeIterator[TResult](IEnumerable)+MoveNext()
at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1)
at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1)
at System.Collections.Immutable.ImmutableArray.CreateRange[T](IEnumerable`1 items)
at System.Collections.Immutable.ImmutableArray.ToImmutableArray[TSource](IEnumerable`1)
at Bicep.Core.Intermediate.ExpressionBuilder.ConvertProgram(ProgramSyntax syntax)
at Bicep.Core.Intermediate.ExpressionBuilder.ConvertWithoutLowering(SyntaxBase syntax)
at Bicep.Core.Intermediate.ExpressionBuilder.Convert(SyntaxBase syntax)
at Bicep.Core.Emit.TemplateWriter.GenerateTemplateWithoutHash(PositionTrackingJsonTextWriter jsonWriter)
at Bicep.Core.Emit.TemplateWriter.Write(SourceAwareJsonTextWriter writer)
at Bicep.Core.Emit.TemplateWriter.<>c__DisplayClass65_0.<EmitModule>b__2()
at Bicep.Core.Emit.PositionTrackingJsonTextWriter.WriteObjectWithPosition(IPositionable sourcePosition, Action propertiesFunc)
at Bicep.Core.Emit.ExpressionEmitter.EmitObject(Action writePropertiesFunc, IPositionable position)
at Bicep.Core.Emit.ExpressionEmitter.<>c__DisplayClass32_0.<EmitObjectProperty>b__0()
at Bicep.Core.Emit.PositionTrackingJsonTextWriter.WritePropertyWithPosition(IPositionable keyPosition, String name, Action valueFunc)
at Bicep.Core.Emit.ExpressionEmitter.EmitProperty(String propertyName, Action writeValueFunc, IPositionable position)
at Bicep.Core.Emit.ExpressionEmitter.EmitObjectProperty(String propertyName, Action writePropertiesFunc, IPositionable position)
at Bicep.Core.Emit.TemplateWriter.<>c__DisplayClass65_0.<EmitModule>b__0()
at Bicep.Core.Emit.PositionTrackingJsonTextWriter.WriteObjectWithPosition(IPositionable sourcePosition, Action propertiesFunc)
at Bicep.Core.Emit.ExpressionEmitter.EmitObject(Action writePropertiesFunc, IPositionable position)
at Bicep.Core.Emit.TemplateWriter.EmitModule(PositionTrackingJsonTextWriter jsonWriter, DeclaredModuleExpression module, ExpressionEmitter emitter)
at Bicep.Core.Emit.TemplateWriter.<>c__DisplayClass61_2.<EmitResources>b__3()
at Bicep.Core.Emit.PositionTrackingJsonTextWriter.WritePropertyWithPosition(IPositionable keyPosition, String name, Action valueFunc)
at Bicep.Core.Emit.ExpressionEmitter.EmitProperty(String propertyName, Action writeValueFunc, IPositionable position)
at Bicep.Core.Emit.TemplateWriter.<>c__DisplayClass61_0.<EmitResources>b__1()
at Bicep.Core.Emit.PositionTrackingJsonTextWriter.WriteObjectWithPosition(IPositionable sourcePosition, Action propertiesFunc)
at Bicep.Core.Emit.ExpressionEmitter.EmitObject(Action writePropertiesFunc, IPositionable position)
at Bicep.Core.Emit.ExpressionEmitter.<>c__DisplayClass32_0.<EmitObjectProperty>b__0()
at Bicep.Core.Emit.PositionTrackingJsonTextWriter.WritePropertyWithPosition(IPositionable keyPosition, String name, Action valueFunc)
at Bicep.Core.Emit.ExpressionEmitter.EmitProperty(String propertyName, Action writeValueFunc, IPositionable position)
at Bicep.Core.Emit.ExpressionEmitter.EmitObjectProperty(String propertyName, Action writePropertiesFunc, IPositionable position)
at Bicep.Core.Emit.TemplateWriter.EmitResources(PositionTrackingJsonTextWriter jsonWriter, ExpressionEmitter emitter, ImmutableArray`1 resources, ImmutableArray`1 modules)
at Bicep.Core.Emit.TemplateWriter.GenerateTemplateWithoutHash(PositionTrackingJsonTextWriter jsonWriter)
at Bicep.Core.Emit.TemplateWriter.Write(SourceAwareJsonTextWriter writer)
at Bicep.Core.Emit.TemplateEmitter.<>c__DisplayClass8_0.<Emit>b__0()
at Bicep.Core.Emit.TemplateEmitter.EmitOrFail(Func`1 write)
at Bicep.Core.Emit.TemplateEmitter.Emit(TextWriter textWriter)
at Bicep.Core.Emit.CompilationEmitter.Template(SemanticModel model)
at Bicep.Core.Emit.CompilationEmitter.Parameters()
at Bicep.Cli.Services.OutputWriter.ParametersToStdout(Compilation compilation)
at Bicep.Cli.Commands.BuildParamsCommand.RunAsync(BuildParamsArguments args)
at Bicep.Cli.Program.RunAsync(String[] args, CancellationToken cancellationToken)
at Bicep.Cli.Program.<>c__DisplayClass3_0.<<Main>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Bicep.Cli.Program.RunWithCancellationAsync(Func`2 runFunc)
at Bicep.Cli.Program.Main(String[] args)
at Bicep.Cli.Program.<Main>(String[] args)
This is a bug with the optional module names feature. The linter doesn't take the possibility of an optional name into account.
The generated name expression of a module in a loop is dependent on the copyIndex() function, so the linter should pass in that situation.