Calamari tentacle throws Index was out of range ArgumentOutOfRangeException on variables parsing

Hi all,

We are experiencing a very strange situation. When a Tentacle Calamari starts any deployment steps it throws the following exception

	System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. 
	April 15th 2020 17:35:35Error
	Parameter name: index 
	at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) 
	at System.Collections.Generic.List`1.get_Item(Int32 index) 
	at Octostache.CustomStringParsers.JsonParser.TryParseJArray(JArray jarray, String property, Binding& subBinding) 
	at Octostache.CustomStringParsers.JsonParser.TryParse(Binding parentBinding, String property, Binding& subBinding) 
	at Octostache.Templates.EvaluationContext.TryCustomParsers(Binding parentBinding, String property, Binding& subBinding) 
	at Octostache.Templates.EvaluationContext.WalkTo(SymbolExpression expression, String[]& missingTokens) 
	at Octostache.Templates.TemplateEvaluator.Calculate(ContentExpression expression, EvaluationContext context) 
	at Octostache.Templates.TemplateEvaluator.EvaluateSubstitutionToken(EvaluationContext context, SubstitutionToken st) 
	at Octostache.Templates.TemplateEvaluator.Evaluate(IEnumerable`1 tokens, EvaluationContext context) 
	at Octostache.Templates.TemplateEvaluator.Evaluate(Template template, EvaluationContext context, String[]& missingTokens) 
	at Octostache.VariableDictionary.Evaluate(String expressionOrVariableOrText, String& error, Boolean haltOnError) 
	at Octostache.VariableDictionary.Get(String variableName, String& error, String defaultValue) 
	at Calamari.Variables.CalamariVariables.Calamari.IVariables.Get(String variableName, String defaultValue) 
	at Calamari.Integration.Scripting.WindowsPowerShell.PowerShellBootstrapper.GetEncryptedVariablesString(IVariables variables) 
	at Calamari.Integration.Scripting.WindowsPowerShell.PowerShellBootstrapper.PrepareBootstrapFile(Script script, IVariables variables) 
	at Calamari.Integration.Scripting.WindowsPowerShell.PowerShellScriptEngine.<PrepareExecution>d__1.MoveNext() 
	at Calamari.Integration.Scripting.ScriptEngine.Execute(Script script, IVariables variables, ICommandLineRunner commandLineRunner, Dictionary`2 environmentVars) 
	at Calamari.Deployment.Conventions.ExecuteScriptConvention.Install(RunningDeployment deployment) 
	at Calamari.Deployment.ConventionProcessor.RunInstallConventions() 
	at Calamari.Deployment.ConventionProcessor.RunConventions() 
	April 15th 2020 17:35:35Error
	Running rollback conventions... 
	April 15th 2020 17:35:35Error
	Index was out of range. Must be non-negative and less than the size of the collection. 
	April 15th 2020 17:35:35Error
	Parameter name: index 
	April 15th 2020 17:35:35Error
	System.ArgumentOutOfRangeException 
	at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) 
	at System.Collections.Generic.List`1.get_Item(Int32 index) 
	at Octostache.CustomStringParsers.JsonParser.TryParseJArray(JArray jarray, String property, Binding& subBinding) 
	at Octostache.CustomStringParsers.JsonParser.TryParse(Binding parentBinding, String property, Binding& subBinding) 
	at Octostache.Templates.EvaluationContext.TryCustomParsers(Binding parentBinding, String property, Binding& subBinding) 
	at Octostache.Templates.EvaluationContext.WalkTo(SymbolExpression expression, String[]& missingTokens) 
	at Octostache.Templates.TemplateEvaluator.Calculate(ContentExpression expression, EvaluationContext context) 
	at Octostache.Templates.TemplateEvaluator.EvaluateSubstitutionToken(EvaluationContext context, SubstitutionToken st) 
	at Octostache.Templates.TemplateEvaluator.Evaluate(IEnumerable`1 tokens, EvaluationContext context) 
	at Octostache.Templates.TemplateEvaluator.Evaluate(Template template, EvaluationContext context, String[]& missingTokens) 
	at Octostache.VariableDictionary.Evaluate(String expressionOrVariableOrText, String& error, Boolean haltOnError) 
	at Octostache.VariableDictionary.Get(String variableName, String& error, String defaultValue) 
	at Calamari.Variables.CalamariVariables.Calamari.IVariables.Get(String variableName, String defaultValue) 
	at Calamari.Integration.Scripting.WindowsPowerShell.PowerShellBootstrapper.GetEncryptedVariablesString(IVariables variables) 
	at Calamari.Integration.Scripting.WindowsPowerShell.PowerShellBootstrapper.PrepareBootstrapFile(Script script, IVariables variables) 
	at Calamari.Integration.Scripting.WindowsPowerShell.PowerShellScriptEngine.<PrepareExecution>d__1.MoveNext() 
	at Calamari.Integration.Scripting.ScriptEngine.Execute(Script script, IVariables variables, ICommandLineRunner commandLineRunner, Dictionary`2 environmentVars) 
	at Calamari.Deployment.Conventions.ExecuteScriptConvention.Install(RunningDeployment deployment) 
	at Calamari.Deployment.ConventionProcessor.RunInstallConventions() 
	at Calamari.Deployment.ConventionProcessor.RunConventions() 
	at Calamari.Commands.RunScriptCommand.Execute(String[] commandLineArguments) 
	at Calamari.Program.Run(CommonOptions options) 
	at Calamari.Program.Main(String[] args) 
	April 15th 2020 17:35:35Fatal
	The remote script failed with exit code 100

Has anyone seen anything like this before?

Thanks for your help

I found part of the issue after downloading the Git Calamari source code and adding Log entries. It would be beneficial to have a similar Log entry at least in the verbose console output, as currently there is no way to know which variable is failing or has issues.

C:\Projects\Calamari\source\Calamari.Shared\Integration\Scripting\WindowsPowerShell\PowerShellBootstrapper.cs

static (string encrypted, string iv) GetEncryptedVariablesString(IVariables variables)
{
	var sb = new StringBuilder();
	foreach (var variableName in variables.GetNames().Where(name => !SpecialVariables.IsLibraryScriptModule(name)))
	{
		Log.Info($">>> GetEncryptedVariablesString '{variableName}'");
		var value = variables.Get(variableName);
		var encryptedValue = value == null ? "nul" : EncodeAsBase64(value); // "nul" is not a valid Base64 string
		sb.Append(EncodeAsBase64(variableName)).Append("$").AppendLine(encryptedValue);
	}
	...
}

The error is thrown from the method Octostache.Templates.TemplateEvaluator.EvaluateSubstitutionToken(EvaluationContext context, SubstitutionToken st)

The problem is a combination of having JIRA Plugin configured and the Send Email step (also MS Teams)
I was trying to use the following template

<h1>Deployment of #{Octopus.Project.Name} #{Octopus.Release.Number} to #{Octopus.Environment.Name} </h1>
<h2><p>View the <a href="#{Octopus.Web.BaseUrl}#{Octopus.Web.DeploymentLink}">detailed deployment log.</a></p></h2>
<h1>Build Information</h1>
<h3>
PackageId: #{Octopus.Deployment.Changes[0].BuildInformation[0].PackageId}<br>
Version: #{Octopus.Deployment.Changes[0].BuildInformation[0].Version}<br>
BuildNumber: #{Octopus.Deployment.Changes[0].BuildInformation[0].BuildNumber}<br>
BuildUrl: #{Octopus.Deployment.Changes[0].BuildInformation[0].BuildUrl}<br>
Branch: #{Octopus.Deployment.Changes[0].BuildInformation[0].Branch}<br>
VcsType: #{Octopus.Deployment.Changes[0].BuildInformation[0].VcsType}<br>
VcsRoot: #{Octopus.Deployment.Changes[0].BuildInformation[0].VcsRoot}<br>
</h3>
<h2><p>The Build Information included the following actions:</p></h2>
<ul>
#{each commit in Octopus.Deployment.Changes[0].Commits}
    <h3> 
          Id: #{commit.Id}<br>
          LinkUrl: #{commit.LinkUrl}<br>
          Comment: #{commit.Comment}
    </h3>
#{/each}
</ul>
<h3>Task summary</h3>
<ol>
#{each step in Octopus.Step}
  #{if step.Status.Code}
    <li>#{step | HtmlEscape} &mdash; <strong>#{step.Status.Code}</strong>
    #{if step.Status.Error}
      <pre>#{step.Status.Error | HtmlEscape}</pre>
      <pre>#{step.Status.ErrorDetail | HtmlEscape}</pre>
    #{/if}  
    </li>
  #{/if}
#{/each}
</ol>

But after many tests, the only stable template is the one below (which is too simplified)

<h1>Deployment of #{Octopus.Project.Name} #{Octopus.Release.Number} to #{Octopus.Environment.Name} </h1>
<h2><p>View the <a href="#{Octopus.Web.BaseUrl}#{Octopus.Web.DeploymentLink}">detailed deployment log.</a></p></h2>
<h1>Build Information</h1>

I added these details to the Octopus support response. I will update any progress

1 Like