{"record":{"id":"dfac7b19f01c0579","repo":"go-delve/delve","slug":"invalid-argument-s-type-s-for-len","errorCode":null,"errorMessage":"invalid argument %s (type %s) for len","messagePattern":"invalid argument (.+?) \\(type (.+?)\\) for len","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/eval.go","lineNumber":1930,"sourceCode":"\t\targ.loadValue(LoadFullValue())\n\t\tif arg.Unreadable != nil {\n\t\t\treturn nil, arg.Unreadable\n\t\t}\n\t\tif arg.Base == 0 {\n\t\t\treturn newConstant(constant.MakeInt64(0), arg.bi, arg.mem), nil\n\t\t}\n\t\treturn newConstant(arg.Children[1].Value, arg.bi, arg.mem), nil\n\tdefault:\n\t\treturn nil, invalidArgErr\n\t}\n}\n\nfunc lenBuiltin(args []*Variable, nodeargs []ast.Expr) (*Variable, error) {\n\tif len(args) != 1 {\n\t\treturn nil, fmt.Errorf(\"wrong number of arguments to len: %d\", len(args))\n\t}\n\targ := args[0]\n\tinvalidArgErr := fmt.Errorf(\"invalid argument %s (type %s) for len\", astutil.ExprToString(nodeargs[0]), arg.TypeString())\n\n\tswitch arg.Kind {\n\tcase reflect.Ptr:\n\t\targ = arg.maybeDereference()\n\t\tif arg.Kind != reflect.Array {\n\t\t\treturn nil, invalidArgErr\n\t\t}\n\t\tfallthrough\n\tcase reflect.Array, reflect.Slice, reflect.String:\n\t\tif arg.Unreadable != nil {\n\t\t\treturn nil, arg.Unreadable\n\t\t}\n\t\treturn newConstant(constant.MakeInt64(arg.Len), arg.bi, arg.mem), nil\n\tcase reflect.Chan:\n\t\targ.loadValue(LoadFullValue())\n\t\tif arg.Unreadable != nil {\n\t\t\treturn nil, arg.Unreadable\n\t\t}","sourceCodeStart":1912,"sourceCodeEnd":1948,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/eval.go#L1912-L1948","documentation":"Delve's `len()` builtin throws this when its single argument's type has no length: valid kinds are string, slice, map, channel, array (or pointer to array after dereference). The error message includes the argument's source text and type string.","triggerScenarios":"Evaluating `len(x)` where x's reflect.Kind is Int, Float, Struct, Func, Bool, Ptr-to-non-array, etc. (eval.go:1930, lenBuiltin).","commonSituations":"`len(myInt)`, `len(myStruct)`, `len(funcVal)`, or a pointer arg that dereferences to a non-array, plus cases where optimized-out variables resolve to an unexpected type.","solutions":["Verify the argument type with `ptype <expr>`; len needs string/slice/map/chan/array.","For numbers or bools, drop len entirely.","For a struct, len the specific slice/map/string field: `len(s.field)`.","If a pointer should point at an array, dereference and confirm the pointee type."],"exampleFix":"// before\nlen(myStruct)\n// after\nlen(myStruct.Items)","handlingStrategy":"type-guard","validationCode":"// before evaluating len(x)\nswitch v.Kind {\ncase reflect.String, reflect.Slice, reflect.Map, reflect.Chan, reflect.Array:\n    // ok\ncase reflect.Ptr:\n    // ok only if dereferenced kind is Array\ndefault:\n    return fmt.Errorf(\"len not defined on %s\", v.TypeString())\n}","typeGuard":"func isLenable(v *proc.Variable) bool {\n    switch v.Kind {\n    case reflect.String, reflect.Slice, reflect.Map, reflect.Chan, reflect.Array:\n        return true\n    case reflect.Ptr:\n        return v.MaybeDereference().Kind == reflect.Array\n    }\n    return false\n}","tryCatchPattern":"val, err := evalLen(expr)\nif err != nil && strings.Contains(err.Error(), \"invalid argument\") {\n    // print the type and suggest the correct field/builtin\n}","preventionTips":["Confirm the type with ptype before calling len.","For structs, len the specific slice/map/string field.","Drop len on numeric/bool values — it has no meaning there."],"tags":["debugger","go","expression-evaluation","builtin-len"],"backgroundTag":"invalid-builtin-argument","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}