{"record":{"id":"a71e12435e1ae6dc","repo":"hashicorp/terraform","slug":"lookup-takes-two-or-three-arguments-got-d","errorCode":null,"errorMessage":"lookup() takes two or three arguments, got %d","messagePattern":"lookup\\(\\) takes two or three arguments, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/lang/funcs/collection.go","lineNumber":248,"sourceCode":"\t\t},\n\t\t{\n\t\t\tName:         \"key\",\n\t\t\tType:         cty.String,\n\t\t\tAllowMarked:  true,\n\t\t\tAllowUnknown: true,\n\t\t},\n\t},\n\tVarParam: &function.Parameter{\n\t\tName:             \"default\",\n\t\tType:             cty.DynamicPseudoType,\n\t\tAllowUnknown:     true,\n\t\tAllowDynamicType: true,\n\t\tAllowNull:        true,\n\t\tAllowMarked:      true,\n\t},\n\tType: func(args []cty.Value) (ret cty.Type, err error) {\n\t\tif len(args) < 1 || len(args) > 3 {\n\t\t\treturn cty.NilType, fmt.Errorf(\"lookup() takes two or three arguments, got %d\", len(args))\n\t\t}\n\n\t\tty := args[0].Type()\n\n\t\tswitch {\n\t\tcase ty.IsObjectType():\n\t\t\tif !args[1].IsKnown() {\n\t\t\t\treturn cty.DynamicPseudoType, nil\n\t\t\t}\n\n\t\t\tkeyVal, _ := args[1].Unmark()\n\t\t\tkey := keyVal.AsString()\n\t\t\tif ty.HasAttribute(key) {\n\t\t\t\treturn args[0].GetAttr(key).Type(), nil\n\t\t\t} else if len(args) == 3 {\n\t\t\t\t// if the key isn't found but a default is provided,\n\t\t\t\t// return the default type\n\t\t\t\treturn args[2].Type(), nil","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/lang/funcs/collection.go#L230-L266","documentation":"lookup() type-check error: the HCL lookup() function accepts exactly two mandatory arguments (map, key) plus an optional third (default). The function's Type callback rejects arg counts outside [1,3] -- but note the message says 'two or three arguments, got N' while the actual gate is len(args) < 1 || len(args) > 3, so it triggers on 0 args or >3 args (the message wording reflects the expected end-user signature, not the raw check).","triggerScenarios":"Calling lookup() with zero arguments, or with more than three arguments (e.g. lookup(map, key, default1, default2)). The VarParam absorbs extras only up to the internal cap of 3.","commonSituations":"Wrong number of trailing commas, a splat/for-expression that produced too many positional args, copy-paste adding an extra default value.","solutions":["Use exactly lookup(map, key) or lookup(map, key, default).","Remove extra positional arguments; if multiple defaults are needed, combine them with coalesce inside the default slot."],"exampleFix":"// before\nval = lookup(var.map, \"k\", var.def1, var.def2)\n\n// after\nval = lookup(var.map, \"k\", coalesce(var.def1, var.def2))","handlingStrategy":"validation","validationCode":"// Use exactly the supported arity.\nlocals { v = length([var.map, var.key]) == 2 ? lookup(var.map, var.key) : lookup(var.map, var.key, var.default) }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Limit lookup() to 2 or 3 arguments.","Combine multiple defaults with coalesce inside the third arg.","Run terraform validate early to catch arity errors."],"tags":["terraform","hcl-functions","lookup","argument-count","validation"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}