Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

element() function is broken with negative indices #36369

Closed
yermulnik opened this issue Jan 20, 2025 · 2 comments · Fixed by #36376
Closed

element() function is broken with negative indices #36369

yermulnik opened this issue Jan 20, 2025 · 2 comments · Fixed by #36376
Labels
bug confirmed a Terraform Core team member has reproduced this issue cty Use in conjunction with "upstream" when cty is the relevant upstream upstream

Comments

@yermulnik
Copy link

Terraform Version

Terraform v1.10.4
on linux_amd64

Terraform Configuration Files

> cat ~/.terraformrc
plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"

Debug Output

# running in empty directory
> echo 'element([1,2,3], -1)' | TF_LOG=trace terraform console -no-color
2025-01-21T00:34:03.385+0200 [INFO]  Terraform version: 1.10.4
2025-01-21T00:34:03.385+0200 [DEBUG] using github.com/hashicorp/go-tfe v1.70.0
2025-01-21T00:34:03.385+0200 [DEBUG] using github.com/hashicorp/hcl/v2 v2.23.0
2025-01-21T00:34:03.385+0200 [DEBUG] using github.com/hashicorp/terraform-svchost v0.1.1
2025-01-21T00:34:03.385+0200 [DEBUG] using github.com/zclconf/go-cty v1.16.0
2025-01-21T00:34:03.385+0200 [INFO]  Go runtime version: go1.23.3
2025-01-21T00:34:03.385+0200 [INFO]  CLI args: []string{"terraform", "console", "-no-color"}
2025-01-21T00:34:03.385+0200 [TRACE] Stdout is not a terminal
2025-01-21T00:34:03.385+0200 [TRACE] Stderr is not a terminal
2025-01-21T00:34:03.385+0200 [TRACE] Stdin is not a terminal
2025-01-21T00:34:03.385+0200 [DEBUG] Attempting to open CLI config file: /home/georgii/.terraformrc
2025-01-21T00:34:03.385+0200 [INFO]  Loading CLI configuration from /home/georgii/.terraformrc
2025-01-21T00:34:03.385+0200 [INFO]  Loading CLI configuration from /home/georgii/.terraform.d/credentials.tfrc.json
2025-01-21T00:34:03.386+0200 [DEBUG] ignoring non-existing provider search directory terraform.d/plugins
2025-01-21T00:34:03.386+0200 [DEBUG] ignoring non-existing provider search directory /home/georgii/.terraform.d/plugins
2025-01-21T00:34:03.386+0200 [DEBUG] ignoring non-existing provider search directory /home/georgii/.local/share/terraform/plugins
2025-01-21T00:34:03.386+0200 [DEBUG] ignoring non-existing provider search directory /home/linuxbrew/.linuxbrew/share/terraform/plugins
2025-01-21T00:34:03.386+0200 [DEBUG] ignoring non-existing provider search directory /usr/share/mate/terraform/plugins
2025-01-21T00:34:03.386+0200 [DEBUG] ignoring non-existing provider search directory /usr/share/gnome/terraform/plugins
2025-01-21T00:34:03.386+0200 [DEBUG] ignoring non-existing provider search directory /home/georgii/.local/share/flatpak/exports/share/terraform/plugins
2025-01-21T00:34:03.386+0200 [DEBUG] ignoring non-existing provider search directory /var/lib/flatpak/exports/share/terraform/plugins
2025-01-21T00:34:03.386+0200 [DEBUG] ignoring non-existing provider search directory /usr/local/share/terraform/plugins
2025-01-21T00:34:03.386+0200 [DEBUG] ignoring non-existing provider search directory /usr/share/terraform/plugins
2025-01-21T00:34:03.386+0200 [DEBUG] ignoring non-existing provider search directory /var/lib/snapd/desktop/terraform/plugins
2025-01-21T00:34:03.386+0200 [INFO]  CLI command args: []string{"console", "-no-color"}
2025-01-21T00:34:03.387+0200 [TRACE] Meta.Backend: no config given or present on disk, so returning nil config
2025-01-21T00:34:03.387+0200 [TRACE] Meta.Backend: backend has not previously been initialized in this working directory
2025-01-21T00:34:03.387+0200 [TRACE] Meta.Backend: using default local state only (no backend configuration, and no existing initialized backend)
2025-01-21T00:34:03.387+0200 [TRACE] Meta.Backend: instantiated backend of type <nil>
2025-01-21T00:34:03.387+0200 [DEBUG] checking for provisioner in "."
2025-01-21T00:34:03.387+0200 [DEBUG] checking for provisioner in "/home/georgii/.terraform.versions"
2025-01-21T00:34:03.387+0200 [TRACE] Meta.Backend: backend <nil> does not support operations, so wrapping it in a local backend
2025-01-21T00:34:03.387+0200 [TRACE] backend/local: CLI option -state is overriding state path to terraform.tfstate
2025-01-21T00:34:03.388+0200 [TRACE] backend/local: requesting state manager for workspace "default"
2025-01-21T00:34:03.388+0200 [TRACE] backend/local: state manager for workspace "default" will:
 - read initial snapshot from terraform.tfstate
 - write new snapshots to terraform.tfstate
 - create any backup at terraform.tfstate.backup
2025-01-21T00:34:03.388+0200 [TRACE] backend/local: requesting state lock for workspace "default"
2025-01-21T00:34:03.388+0200 [TRACE] statemgr.Filesystem: preparing to manage state snapshots at terraform.tfstate
2025-01-21T00:34:03.388+0200 [TRACE] statemgr.Filesystem: no previously-stored snapshot exists
2025-01-21T00:34:03.388+0200 [TRACE] statemgr.Filesystem: locking terraform.tfstate using fcntl flock
2025-01-21T00:34:03.388+0200 [TRACE] statemgr.Filesystem: writing lock metadata to .terraform.tfstate.lock.info
2025-01-21T00:34:03.388+0200 [TRACE] backend/local: reading remote state for workspace "default"
2025-01-21T00:34:03.388+0200 [TRACE] statemgr.Filesystem: reading latest snapshot from terraform.tfstate
2025-01-21T00:34:03.388+0200 [TRACE] statemgr.Filesystem: snapshot file has nil snapshot, but that's okay
2025-01-21T00:34:03.388+0200 [TRACE] statemgr.Filesystem: read nil snapshot
2025-01-21T00:34:03.388+0200 [TRACE] backend/local: populating backendrun.LocalRun for current working directory
2025-01-21T00:34:03.389+0200 [TRACE] terraform.NewContext: starting
2025-01-21T00:34:03.389+0200 [TRACE] terraform.NewContext: complete
2025-01-21T00:34:03.389+0200 [DEBUG] Building and walking 'eval' graph
2025-01-21T00:34:03.389+0200 [TRACE] Executing graph transform *terraform.ConfigTransformer
2025-01-21T00:34:03.389+0200 [TRACE] ConfigTransformer: Starting for path:
2025-01-21T00:34:03.389+0200 [TRACE] Completed graph transform *terraform.ConfigTransformer (no changes)
2025-01-21T00:34:03.389+0200 [TRACE] Executing graph transform *terraform.RootVariableTransformer
2025-01-21T00:34:03.389+0200 [TRACE] Completed graph transform *terraform.RootVariableTransformer (no changes)
2025-01-21T00:34:03.389+0200 [TRACE] Executing graph transform *terraform.ModuleVariableTransformer
2025-01-21T00:34:03.389+0200 [TRACE] Completed graph transform *terraform.ModuleVariableTransformer (no changes)
2025-01-21T00:34:03.389+0200 [TRACE] Executing graph transform *terraform.variableValidationTransformer
2025-01-21T00:34:03.389+0200 [TRACE] variableValidationTransformer: adding validation nodes for any existing variable evaluation nodes
2025-01-21T00:34:03.389+0200 [TRACE] Completed graph transform *terraform.variableValidationTransformer (no changes)
2025-01-21T00:34:03.389+0200 [TRACE] Executing graph transform *terraform.LocalTransformer
2025-01-21T00:34:03.389+0200 [TRACE] Completed graph transform *terraform.LocalTransformer (no changes)
2025-01-21T00:34:03.389+0200 [TRACE] Executing graph transform *terraform.OutputTransformer
2025-01-21T00:34:03.389+0200 [TRACE] Completed graph transform *terraform.OutputTransformer (no changes)
2025-01-21T00:34:03.389+0200 [TRACE] Executing graph transform *terraform.AttachResourceConfigTransformer
2025-01-21T00:34:03.389+0200 [TRACE] Completed graph transform *terraform.AttachResourceConfigTransformer (no changes)
2025-01-21T00:34:03.389+0200 [TRACE] Executing graph transform *terraform.AttachStateTransformer
2025-01-21T00:34:03.389+0200 [DEBUG] Not attaching any node states: overall state is nil
2025-01-21T00:34:03.389+0200 [TRACE] Completed graph transform *terraform.AttachStateTransformer (no changes)
2025-01-21T00:34:03.389+0200 [TRACE] Executing graph transform *terraform.graphTransformerMulti
2025-01-21T00:34:03.389+0200 [TRACE] (graphTransformerMulti) Executing graph transform *terraform.externalProviderTransformer
2025-01-21T00:34:03.389+0200 [TRACE] (graphTransformerMulti) Completed graph transform *terraform.externalProviderTransformer (no changes)
2025-01-21T00:34:03.389+0200 [TRACE] (graphTransformerMulti) Executing graph transform *terraform.ProviderConfigTransformer
2025-01-21T00:34:03.389+0200 [TRACE] (graphTransformerMulti) Completed graph transform *terraform.ProviderConfigTransformer (no changes)
2025-01-21T00:34:03.389+0200 [TRACE] (graphTransformerMulti) Executing graph transform *terraform.MissingProviderTransformer
2025-01-21T00:34:03.389+0200 [TRACE] (graphTransformerMulti) Completed graph transform *terraform.MissingProviderTransformer (no changes)
2025-01-21T00:34:03.389+0200 [TRACE] (graphTransformerMulti) Executing graph transform *terraform.ProviderTransformer
2025-01-21T00:34:03.389+0200 [TRACE] (graphTransformerMulti) Completed graph transform *terraform.ProviderTransformer (no changes)
2025-01-21T00:34:03.389+0200 [TRACE] (graphTransformerMulti) Executing graph transform *terraform.PruneProviderTransformer
2025-01-21T00:34:03.389+0200 [TRACE] (graphTransformerMulti) Completed graph transform *terraform.PruneProviderTransformer (no changes)
2025-01-21T00:34:03.389+0200 [TRACE] Completed graph transform *terraform.graphTransformerMulti (no changes)
2025-01-21T00:34:03.389+0200 [TRACE] Executing graph transform *terraform.AttachSchemaTransformer
2025-01-21T00:34:03.389+0200 [TRACE] Completed graph transform *terraform.AttachSchemaTransformer (no changes)
2025-01-21T00:34:03.389+0200 [TRACE] Executing graph transform *terraform.ModuleExpansionTransformer
2025-01-21T00:34:03.389+0200 [TRACE] Completed graph transform *terraform.ModuleExpansionTransformer (no changes)
2025-01-21T00:34:03.389+0200 [TRACE] Executing graph transform *terraform.ReferenceTransformer
2025-01-21T00:34:03.389+0200 [TRACE] Completed graph transform *terraform.ReferenceTransformer (no changes)
2025-01-21T00:34:03.389+0200 [TRACE] Executing graph transform *terraform.CloseProviderTransformer
2025-01-21T00:34:03.389+0200 [TRACE] Completed graph transform *terraform.CloseProviderTransformer (no changes)
2025-01-21T00:34:03.389+0200 [TRACE] Executing graph transform *terraform.CloseRootModuleTransformer
2025-01-21T00:34:03.389+0200 [TRACE] Completed graph transform *terraform.CloseRootModuleTransformer with new graph:
  root - *terraform.nodeCloseModule
  ------
2025-01-21T00:34:03.389+0200 [TRACE] Executing graph transform *terraform.TransitiveReductionTransformer
2025-01-21T00:34:03.389+0200 [TRACE] Completed graph transform *terraform.TransitiveReductionTransformer (no changes)
2025-01-21T00:34:03.389+0200 [DEBUG] Starting graph walk: walkEval
2025-01-21T00:34:03.389+0200 [TRACE] vertex "root": starting visit (*terraform.nodeCloseModule)
2025-01-21T00:34:03.389+0200 [TRACE] vertex "root": does not belong to any module instance
2025-01-21T00:34:03.389+0200 [TRACE] vertex "root": visit complete

Error: Error in function call

  on <console-input> line 1:
  (source code not available)

Call to function "element" failed: panic in function implementation: runtime
error: index out of range [-1]
goroutine 1 [running]:
runtime/debug.Stack()
	runtime/debug/stack.go:26 +0x5e
github.com/zclconf/go-cty/cty/function.errorForPanic(...)
	github.com/zclconf/go-cty@v1.16.0/cty/function/error.go:44
github.com/zclconf/go-cty/cty/function.Function.returnTypeForValues.func1()
	github.com/zclconf/go-cty@v1.16.0/cty/function/function.go:226 +0x7b
panic({0x352be40?, 0xc0007d1428?})
	runtime/panic.go:785 +0x132
github.com/zclconf/go-cty/cty/function/stdlib.init.func12({0xc0009f5ec0,
0xc0001959e8?, 0x3e20e58?})
	github.com/zclconf/go-cty@v1.16.0/cty/function/stdlib/collection.go:173
+0x25f
github.com/zclconf/go-cty/cty/function.Function.returnTypeForValues({0x0?},
{0xc0009f5ec0, 0x2, 0x0?})
	github.com/zclconf/go-cty@v1.16.0/cty/function/function.go:230 +0x778
github.com/zclconf/go-cty/cty/function.Function.Call({0x3e20e58?},
{0xc0009f5ec0, 0x2, 0x2})
	github.com/zclconf/go-cty@v1.16.0/cty/function/function.go:250 +0x7a
github.com/hashicorp/hcl/v2/hclsyntax.(*FunctionCallExpr).Value(0xc0003ceb40,
0xc0009fa588)
	github.com/hashicorp/hcl/v2@v2.23.0/hclsyntax/expression.go:528 +0x1acf
github.com/hashicorp/terraform/internal/lang.(*Scope).EvalExpr(0xc0007b6480,
{0x3e217e8, 0xc0003ceb40}, {{0x3e218d8?, 0x5a431a0?}})
	github.com/hashicorp/terraform/internal/lang/eval.go:179 +0x1a5
github.com/hashicorp/terraform/internal/repl.(*Session).handleEval(0xc00088f8e8,
{0xc00088f6d8?, 0xc00088f6d8?})
	github.com/hashicorp/terraform/internal/repl/session.go:58 +0x14e
github.com/hashicorp/terraform/internal/repl.(*Session).Handle(0xc00088f8e8,
{0xc00088f6d8, 0x14})
	github.com/hashicorp/terraform/internal/repl/session.go:43 +0xbc
github.com/hashicorp/terraform/internal/command.(*ConsoleCommand).modePiped(0xc000685a40,
0xc00088f8e8, {0x3e290f0, 0xc0009f0330})
	github.com/hashicorp/terraform/internal/command/console.go:191 +0xee
github.com/hashicorp/terraform/internal/command.(*ConsoleCommand).Run(0xc000685a40,
{0xc00018a170?, 0x0?, 0x0?})
	github.com/hashicorp/terraform/internal/command/console.go:181 +0x1073
github.com/hashicorp/cli.(*CLI).Run(0xc0009d2140)
	github.com/hashicorp/cli@v1.1.6/cli.go:265 +0x55f
main.realMain()
	github.com/hashicorp/terraform/main.go:339 +0x1deb
main.main()
	github.com/hashicorp/terraform/main.go:64 +0x13
.

2025-01-21T00:34:03.390+0200 [TRACE] statemgr.Filesystem: removing lock metadata file .terraform.tfstate.lock.info
2025-01-21T00:34:03.390+0200 [TRACE] statemgr.Filesystem: unlocking terraform.tfstate using fcntl flock

Expected Behavior

As of TF 1.10.0 release notes and #35501 I'd expect element() function to accept negative indices and not fail.

Actual Behavior

> echo 'element([1,2,3], -1)' | terraform console -no-color

Error: Error in function call

  on <console-input> line 1:
  (source code not available)

Call to function "element" failed: panic in function implementation: runtime error: index out of range [-1]
goroutine 1 [running]:
runtime/debug.Stack()
        runtime/debug/stack.go:26 +0x5e
github.com/zclconf/go-cty/cty/function.errorForPanic(...)
        github.com/zclconf/go-cty@v1.16.0/cty/function/error.go:44
github.com/zclconf/go-cty/cty/function.Function.returnTypeForValues.func1()
        github.com/zclconf/go-cty@v1.16.0/cty/function/function.go:226 +0x7b
panic({0x352be40?, 0xc000c106a8?})
        runtime/panic.go:785 +0x132
github.com/zclconf/go-cty/cty/function/stdlib.init.func12({0xc000a34780, 0xc000013bf8?, 0x3e20e58?})
        github.com/zclconf/go-cty@v1.16.0/cty/function/stdlib/collection.go:173 +0x25f
github.com/zclconf/go-cty/cty/function.Function.returnTypeForValues({0x0?}, {0xc000a34780, 0x2, 0x0?})
        github.com/zclconf/go-cty@v1.16.0/cty/function/function.go:230 +0x778
github.com/zclconf/go-cty/cty/function.Function.Call({0x3e20e58?}, {0xc000a34780, 0x2, 0x2})
        github.com/zclconf/go-cty@v1.16.0/cty/function/function.go:250 +0x7a
github.com/hashicorp/hcl/v2/hclsyntax.(*FunctionCallExpr).Value(0xc00089a5a0, 0xc000c09d10)
        github.com/hashicorp/hcl/v2@v2.23.0/hclsyntax/expression.go:528 +0x1acf
github.com/hashicorp/terraform/internal/lang.(*Scope).EvalExpr(0xc0002c2ab0, {0x3e217e8, 0xc00089a5a0}, {{0x3e218d8?, 0x5a431a0?}})
        github.com/hashicorp/terraform/internal/lang/eval.go:179 +0x1a5
github.com/hashicorp/terraform/internal/repl.(*Session).handleEval(0xc00081b8e8, {0xc00081b6d8?, 0xc00081b6d8?})
        github.com/hashicorp/terraform/internal/repl/session.go:58 +0x14e
github.com/hashicorp/terraform/internal/repl.(*Session).Handle(0xc00081b8e8, {0xc00081b6d8, 0x14})
        github.com/hashicorp/terraform/internal/repl/session.go:43 +0xbc
github.com/hashicorp/terraform/internal/command.(*ConsoleCommand).modePiped(0xc000584c40, 0xc00081b8e8, {0x3e290f0, 0xc000a0ee10})
        github.com/hashicorp/terraform/internal/command/console.go:191 +0xee
github.com/hashicorp/terraform/internal/command.(*ConsoleCommand).Run(0xc000584c40, {0xc0000721a0?, 0x0?, 0x0?})
        github.com/hashicorp/terraform/internal/command/console.go:181 +0x1073
github.com/hashicorp/cli.(*CLI).Run(0xc000760280)
        github.com/hashicorp/cli@v1.1.6/cli.go:265 +0x55f
main.realMain()
        github.com/hashicorp/terraform/main.go:339 +0x1deb
main.main()
        github.com/hashicorp/terraform/main.go:64 +0x13
.

Steps to Reproduce

echo 'element([1,2,3], -1)' | terraform console

Additional Context

No response

References

Generative AI / LLM assisted development?

No response

@yermulnik yermulnik added bug new new issue not yet triaged labels Jan 20, 2025
@liamcervante liamcervante added upstream confirmed a Terraform Core team member has reproduced this issue cty Use in conjunction with "upstream" when cty is the relevant upstream labels Jan 21, 2025
@liamcervante
Copy link
Member

Hi @yermulnik, thanks for filing this! I've raised zclconf/go-cty#200 with the upstream function library to resolve this.

I'll note here the difference between a tuple and a list. A tuple is of concrete known length, and so the maintainer of the upstream library may not want to add support for unknown indices when referencing a tuple. I do also note the CHANGELOG for the library (and for Terraform) just said the element function supports negative indices and didn't clarify the difference between a tuple and a list.

While we wait for a response there, you can force the input into a list using the tolist(...) function, so element(tolist([0, 1, 2]), -1) does work as expected.

Thanks again!

@liamcervante liamcervante removed the new new issue not yet triaged label Jan 21, 2025
@yermulnik
Copy link
Author

@liamcervante Thanks for filing PR for the underlying library and for the pointer to use list() meanwhile 👍🏻

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug confirmed a Terraform Core team member has reproduced this issue cty Use in conjunction with "upstream" when cty is the relevant upstream upstream
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants