Skip to content

Use of spread when property for expression is also used in the resource body breaks template emitting #19394

@majastrz

Description

@majastrz

Bicep version
0.42.1

Describe the bug
When the spread operator is used in a resource body that is using a [for ...] expression at a sibling node, we emit no diagnostics in the language server but compilation will fail with the following exception:

Internal Error - System.NotImplementedException: Cannot emit unexpected expression of type ForLoopExpression
   at Bicep.Core.Emit.ExpressionConverter.ConvertExpression(Expression expression) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\ExpressionConverter.cs:line 223
   at Bicep.Core.Emit.ExpressionConverter.ConvertObject(ObjectExpression expression) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\ExpressionConverter.cs:line 870
   at Bicep.Core.Emit.ExpressionConverter.ConvertObject(ObjectExpression expression) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\ExpressionConverter.cs:line 870
   at System.Linq.Enumerable.ArraySelectIterator`2.ToArray()
   at Bicep.Core.Emit.ExpressionConverter.CreateFunction(String name, IEnumerable`1 parameters) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\ExpressionConverter.cs:line 1020
   at Bicep.Core.Emit.ExpressionConverter.ConvertArray(ArrayExpression expression) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\ExpressionConverter.cs:line 849
   at System.Linq.Enumerable.ArraySelectIterator`2.ToArray()
   at Bicep.Core.Emit.ExpressionConverter.CreateFunction(String name, IEnumerable`1 parameters) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\ExpressionConverter.cs:line 1020
   at Bicep.Core.Emit.ExpressionConverter.ConvertExpression(Expression expression) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\ExpressionConverter.cs:line 100
   at Bicep.Core.Emit.ExpressionEmitter.EmitLanguageExpression(Expression expression) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\ExpressionEmitter.cs:line 161
   at Bicep.Core.Emit.ExpressionEmitter.EmitExpression(Expression expression) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\ExpressionEmitter.cs:line 77
   at Bicep.Core.Emit.ExpressionEmitter.<>c__DisplayClass23_0.<EmitProperty>b__0() in C:\__w\1\s\bicep\src\Bicep.Core\Emit\ExpressionEmitter.cs:line 388
   at Bicep.Core.Emit.PositionTrackingJsonTextWriter.WritePropertyWithPosition(IPositionable keyPosition, String name, Action valueFunc) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\PositionTrackingJsonTextWriter.cs:line 114
   at Bicep.Core.Emit.ExpressionEmitter.EmitPropertyInternal(LanguageExpression expressionKey, Action valueFunc, IPositionable location, Boolean skipCopyCheck) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\ExpressionEmitter.cs:line 424
   at Bicep.Core.Emit.ExpressionEmitter.EmitProperty(Expression name, Expression expression) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\ExpressionEmitter.cs:line 388
   at Bicep.Core.Emit.ExpressionEmitter.EmitProperty(String name, Expression expression) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\ExpressionEmitter.cs:line 391
   at Bicep.Core.Emit.ExpressionEmitter.EmitObjectProperties(ObjectExpression object) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\ExpressionEmitter.cs:line 303
   at Bicep.Core.Emit.TemplateWriter.<>c__DisplayClass69_0.<EmitResource>b__0() in C:\__w\1\s\bicep\src\Bicep.Core\Emit\TemplateWriter.cs:line 1270
   at Bicep.Core.Emit.PositionTrackingJsonTextWriter.WriteObjectWithPosition(IPositionable sourcePosition, Action propertiesFunc) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\PositionTrackingJsonTextWriter.cs:line 92
   at Bicep.Core.Emit.ExpressionEmitter.EmitObject(Action writePropertiesFunc, IPositionable position) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\ExpressionEmitter.cs:line 446
   at Bicep.Core.Emit.TemplateWriter.EmitResource(ExpressionEmitter emitter, ImmutableArray`1 extensions, DeclaredResourceExpression resource) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\TemplateWriter.cs:line 1208
   at Bicep.Core.Emit.TemplateWriter.<>c__DisplayClass67_0.<EmitResources>b__0() in C:\__w\1\s\bicep\src\Bicep.Core\Emit\TemplateWriter.cs:line 1160
   at Bicep.Core.Emit.PositionTrackingJsonTextWriter.WriteArrayWithPosition(IPositionable sourcePosition, Action itemsFunc) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\PositionTrackingJsonTextWriter.cs:line 103
   at Bicep.Core.Emit.ExpressionEmitter.EmitArray(Action writeItemsFunc, IPositionable position) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\ExpressionEmitter.cs:line 449
   at Bicep.Core.Emit.ExpressionEmitter.<>c__DisplayClass34_0.<EmitArrayProperty>b__0() in C:\__w\1\s\bicep\src\Bicep.Core\Emit\ExpressionEmitter.cs:line 443
   at Bicep.Core.Emit.PositionTrackingJsonTextWriter.WritePropertyWithPosition(IPositionable keyPosition, String name, Action valueFunc) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\PositionTrackingJsonTextWriter.cs:line 114
   at Bicep.Core.Emit.ExpressionEmitter.EmitProperty(String propertyName, Action writeValueFunc, IPositionable position) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\ExpressionEmitter.cs:line 434
   at Bicep.Core.Emit.ExpressionEmitter.EmitArrayProperty(String propertyName, Action writeItemsFunc, IPositionable position) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\ExpressionEmitter.cs:line 443
   at Bicep.Core.Emit.TemplateWriter.EmitResources(PositionTrackingJsonTextWriter jsonWriter, ExpressionEmitter emitter, ImmutableArray`1 extensions, ImmutableArray`1 resources, ImmutableArray`1 modules) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\TemplateWriter.cs:line 1151
   at Bicep.Core.Emit.TemplateWriter.GenerateTemplateWithoutHash(PositionTrackingJsonTextWriter jsonWriter) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\TemplateWriter.cs:line 139
   at Bicep.Core.Emit.TemplateWriter.Write(SourceAwareJsonTextWriter writer) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\TemplateWriter.cs:line 79
   at Bicep.Core.Emit.TemplateEmitter.<>c__DisplayClass8_0.<Emit>b__0() in C:\__w\1\s\bicep\src\Bicep.Core\Emit\TemplateEmitter.cs:line 116
   at Bicep.Core.Emit.TemplateEmitter.EmitOrFail(Func`1 write) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\TemplateEmitter.cs:line 137
   at Bicep.Core.Emit.TemplateEmitter.Emit(TextWriter textWriter) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\TemplateEmitter.cs:line 102
   at Bicep.Core.Emit.CompilationEmitter.Template(SemanticModel model) in C:\__w\1\s\bicep\src\Bicep.Core\Emit\CompilationEmitter.cs:line 106
   at Bicep.Core.Emit.CompilationEmitter.Template() in C:\__w\1\s\bicep\src\Bicep.Core\Emit\CompilationEmitter.cs:line 98
   at Bicep.LanguageServer.Handlers.BicepBuildCommandHandler.Handle(DocumentUri documentUri, CancellationToken cancellationToken) in C:\__w\1\s\bicep\src\Bicep.LangServer\Handlers\BicepBuildCommandHandler.cs:line 56
   at OmniSharp.Extensions.LanguageServer.Server.Pipelines.SemanticTokensDeltaPipeline`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
   at OmniSharp.Extensions.LanguageServer.Server.Pipelines.ResolveCommandPipeline`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
   at MediatR.Pipeline.RequestPreProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
   at MediatR.Pipeline.RequestPostProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
   at MediatR.Pipeline.RequestExceptionProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
   at MediatR.Pipeline.RequestExceptionProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
   at MediatR.Pipeline.RequestExceptionActionProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
   at MediatR.Pipeline.RequestExceptionActionProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
   at OmniSharp.Extensions.JsonRpc.RequestRouterBase`1.<RouteRequest>g__InnerRoute|7_0(IServiceScopeFactory serviceScopeFactory, Request request, TDescriptor descriptor, Object params, CancellationToken token, ILogger logger)
   at OmniSharp.Extensions.JsonRpc.RequestRouterBase`1.RouteRequest(IRequestDescriptor`1 descriptors, Request request, CancellationToken token)
   at OmniSharp.Extensions.JsonRpc.DefaultRequestInvoker.<>c__DisplayClass10_0.<<RouteRequest>b__5>d.MoveNext()

To Reproduce
Minimal repro:

resource foo 'Microsoft.Storage/storageAccounts@2025-08-01' = {
  name: uniqueString(resourceGroup().id, 'repro')
  location: resourceGroup().location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    networkAcls: {
      defaultAction: 'Deny'
      ipRules: [for item in []: {
        value: item
        action: 'Allow'
      }]
    }
    ...{}
  }
}

Additional context
Rewriting the property copy loop to lambda works as a workaround:

resource foo 'Microsoft.Storage/storageAccounts@2025-08-01' = {
  name: uniqueString(resourceGroup().id, 'repro')
  location: resourceGroup().location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    networkAcls: {
      defaultAction: 'Deny'
      ipRules: map([], item => {
        value: item
        action: 'Allow'
      })
    }
    ...{}
  }
}

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions