Repository: goadesign/goa
Pull request #3488 (2024-03-08 21:06:01)

Return a validation error when query string is malformed
for map parameters.

raphael: Fix https://github.com/goadesign/goa/issues/3481

Patch:
diff --git a/http/codegen/service_data.go b/http/codegen/service_data.go
index cee5a002..2f7572ff 100644
--- a/http/codegen/service_data.go
+++ b/http/codegen/service_data.go
@@ -1067,7 +1067,7 @@ func buildPayloadData(e *expr.HTTPEndpointExpr, sd *ServiceData) *PayloadData {
 			}
 			if !mustValidate {
 				for _, q := range queryData {
-					if q.Validate != "" || q.Required || needConversion(q.Type) {
+					if q.Map || q.Validate != "" || q.Required || needConversion(q.Type) {
 						mustValidate = true
 						break
 					}
diff --git a/http/codegen/templates/partial/query_map_conversion.go.tpl b/http/codegen/templates/partial/query_map_conversion.go.tpl
index 4abf0952..6b3bfcc5 100644
--- a/http/codegen/templates/partial/query_map_conversion.go.tpl
+++ b/http/codegen/templates/partial/query_map_conversion.go.tpl
@@ -5,6 +5,9 @@
 	{
 		openIdx := strings.IndexRune(keyRaw, '[')
 		closeIdx := strings.IndexRune(keyRaw, ']')
+		if closeIdx == -1 {
+			err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+		} else {
 	{{- if eq .Type.KeyType.Type.Name "string" }}
 		key{{ .Loop }} = keyRaw[openIdx+1 : closeIdx]
 	{{- else }}
@@ -14,6 +17,7 @@
 		{{- if gt .Depth 0 }}
 			keyRaw = keyRaw[closeIdx+1:]
 		{{- end }}
+		}
 	}
 	{{- if eq .Type.ElemType.Type.Name "string" }}
 		{{ .VarName }}[key{{ .Loop }}] = valRaw[0]


Test patch:
diff --git a/http/codegen/testdata/multipart_code.go b/http/codegen/testdata/multipart_code.go
index fa1ff38f..8e408e94 100644
--- a/http/codegen/testdata/multipart_code.go
+++ b/http/codegen/testdata/multipart_code.go
@@ -161,12 +161,16 @@ func NewServiceMultipartWithParamMethodMultipartWithParamDecoder(mux goahttp.Mux
 						{
 							openIdx := strings.IndexRune(keyRaw, '[')
 							closeIdx := strings.IndexRune(keyRaw, ']')
-							keyaRaw := keyRaw[openIdx+1 : closeIdx]
-							v, err2 := strconv.ParseInt(keyaRaw, 10, strconv.IntSize)
-							if err2 != nil {
-								err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "integer"))
+							if closeIdx == -1 {
+								err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+							} else {
+								keyaRaw := keyRaw[openIdx+1 : closeIdx]
+								v, err2 := strconv.ParseInt(keyaRaw, 10, strconv.IntSize)
+								if err2 != nil {
+									err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "integer"))
+								}
+								keya = int(v)
 							}
-							keya = int(v)
 						}
 						c2[keya] = valRaw
 					}
@@ -221,12 +225,16 @@ func NewServiceMultipartWithParamsAndHeadersMethodMultipartWithParamsAndHeadersD
 						{
 							openIdx := strings.IndexRune(keyRaw, '[')
 							closeIdx := strings.IndexRune(keyRaw, ']')
-							keyaRaw := keyRaw[openIdx+1 : closeIdx]
-							v, err2 := strconv.ParseInt(keyaRaw, 10, strconv.IntSize)
-							if err2 != nil {
-								err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "integer"))
+							if closeIdx == -1 {
+								err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+							} else {
+								keyaRaw := keyRaw[openIdx+1 : closeIdx]
+								v, err2 := strconv.ParseInt(keyaRaw, 10, strconv.IntSize)
+								if err2 != nil {
+									err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "integer"))
+								}
+								keya = int(v)
 							}
-							keya = int(v)
 						}
 						c2[keya] = valRaw
 					}
diff --git a/http/codegen/testdata/payload_decode_functions.go b/http/codegen/testdata/payload_decode_functions.go
index fb927e0b..af54e9e4 100644
--- a/http/codegen/testdata/payload_decode_functions.go
+++ b/http/codegen/testdata/payload_decode_functions.go
@@ -1524,7 +1524,8 @@ var PayloadQueryMapStringStringDecodeCode = `// DecodeMethodQueryMapStringString
 func DecodeMethodQueryMapStringStringRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Decoder) func(*http.Request) (any, error) {
 	return func(r *http.Request) (any, error) {
 		var (
-			q map[string]string
+			q   map[string]string
+			err error
 		)
 		{
 			qRaw := r.URL.Query()
@@ -1538,13 +1539,20 @@ func DecodeMethodQueryMapStringStringRequest(mux goahttp.Muxer, decoder func(*ht
 						{
 							openIdx := strings.IndexRune(keyRaw, '[')
 							closeIdx := strings.IndexRune(keyRaw, ']')
-							keya = keyRaw[openIdx+1 : closeIdx]
+							if closeIdx == -1 {
+								err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+							} else {
+								keya = keyRaw[openIdx+1 : closeIdx]
+							}
 						}
 						q[keya] = valRaw[0]
 					}
 				}
 			}
 		}
+		if err != nil {
+			return nil, err
+		}
 		payload := NewMethodQueryMapStringStringPayload(q)
 
 		return payload, nil
@@ -1575,7 +1583,11 @@ func DecodeMethodQueryMapStringStringValidateRequest(mux goahttp.Muxer, decoder
 					{
 						openIdx := strings.IndexRune(keyRaw, '[')
 						closeIdx := strings.IndexRune(keyRaw, ']')
-						keya = keyRaw[openIdx+1 : closeIdx]
+						if closeIdx == -1 {
+							err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+						} else {
+							keya = keyRaw[openIdx+1 : closeIdx]
+						}
 					}
 					q[keya] = valRaw[0]
 				}
@@ -1622,7 +1634,11 @@ func DecodeMethodQueryMapStringBoolRequest(mux goahttp.Muxer, decoder func(*http
 						{
 							openIdx := strings.IndexRune(keyRaw, '[')
 							closeIdx := strings.IndexRune(keyRaw, ']')
-							keya = keyRaw[openIdx+1 : closeIdx]
+							if closeIdx == -1 {
+								err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+							} else {
+								keya = keyRaw[openIdx+1 : closeIdx]
+							}
 						}
 						var vala bool
 						{
@@ -1671,7 +1687,11 @@ func DecodeMethodQueryMapStringBoolValidateRequest(mux goahttp.Muxer, decoder fu
 					{
 						openIdx := strings.IndexRune(keyRaw, '[')
 						closeIdx := strings.IndexRune(keyRaw, ']')
-						keya = keyRaw[openIdx+1 : closeIdx]
+						if closeIdx == -1 {
+							err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+						} else {
+							keya = keyRaw[openIdx+1 : closeIdx]
+						}
 					}
 					var vala bool
 					{
@@ -1727,12 +1747,16 @@ func DecodeMethodQueryMapBoolStringRequest(mux goahttp.Muxer, decoder func(*http
 						{
 							openIdx := strings.IndexRune(keyRaw, '[')
 							closeIdx := strings.IndexRune(keyRaw, ']')
-							keyaRaw := keyRaw[openIdx+1 : closeIdx]
-							v, err2 := strconv.ParseBool(keyaRaw)
-							if err2 != nil {
-								err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "boolean"))
+							if closeIdx == -1 {
+								err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+							} else {
+								keyaRaw := keyRaw[openIdx+1 : closeIdx]
+								v, err2 := strconv.ParseBool(keyaRaw)
+								if err2 != nil {
+									err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "boolean"))
+								}
+								keya = v
 							}
-							keya = v
 						}
 						q[keya] = valRaw[0]
 					}
@@ -1772,12 +1796,16 @@ func DecodeMethodQueryMapBoolStringValidateRequest(mux goahttp.Muxer, decoder fu
 					{
 						openIdx := strings.IndexRune(keyRaw, '[')
 						closeIdx := strings.IndexRune(keyRaw, ']')
-						keyaRaw := keyRaw[openIdx+1 : closeIdx]
-						v, err2 := strconv.ParseBool(keyaRaw)
-						if err2 != nil {
-							err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "boolean"))
+						if closeIdx == -1 {
+							err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+						} else {
+							keyaRaw := keyRaw[openIdx+1 : closeIdx]
+							v, err2 := strconv.ParseBool(keyaRaw)
+							if err2 != nil {
+								err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "boolean"))
+							}
+							keya = v
 						}
-						keya = v
 					}
 					q[keya] = valRaw[0]
 				}
@@ -1824,12 +1852,16 @@ func DecodeMethodQueryMapBoolBoolRequest(mux goahttp.Muxer, decoder func(*http.R
 						{
 							openIdx := strings.IndexRune(keyRaw, '[')
 							closeIdx := strings.IndexRune(keyRaw, ']')
-							keyaRaw := keyRaw[openIdx+1 : closeIdx]
-							v, err2 := strconv.ParseBool(keyaRaw)
-							if err2 != nil {
-								err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "boolean"))
+							if closeIdx == -1 {
+								err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+							} else {
+								keyaRaw := keyRaw[openIdx+1 : closeIdx]
+								v, err2 := strconv.ParseBool(keyaRaw)
+								if err2 != nil {
+									err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "boolean"))
+								}
+								keya = v
 							}
-							keya = v
 						}
 						var vala bool
 						{
@@ -1878,12 +1910,16 @@ func DecodeMethodQueryMapBoolBoolValidateRequest(mux goahttp.Muxer, decoder func
 					{
 						openIdx := strings.IndexRune(keyRaw, '[')
 						closeIdx := strings.IndexRune(keyRaw, ']')
-						keyaRaw := keyRaw[openIdx+1 : closeIdx]
-						v, err2 := strconv.ParseBool(keyaRaw)
-						if err2 != nil {
-							err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "boolean"))
+						if closeIdx == -1 {
+							err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+						} else {
+							keyaRaw := keyRaw[openIdx+1 : closeIdx]
+							v, err2 := strconv.ParseBool(keyaRaw)
+							if err2 != nil {
+								err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "boolean"))
+							}
+							keya = v
 						}
-						keya = v
 					}
 					var vala bool
 					{
@@ -1925,7 +1961,8 @@ var PayloadQueryMapStringArrayStringDecodeCode = `// DecodeMethodQueryMapStringA
 func DecodeMethodQueryMapStringArrayStringRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Decoder) func(*http.Request) (any, error) {
 	return func(r *http.Request) (any, error) {
 		var (
-			q map[string][]string
+			q   map[string][]string
+			err error
 		)
 		{
 			qRaw := r.URL.Query()
@@ -1939,13 +1976,20 @@ func DecodeMethodQueryMapStringArrayStringRequest(mux goahttp.Muxer, decoder fun
 						{
 							openIdx := strings.IndexRune(keyRaw, '[')
 							closeIdx := strings.IndexRune(keyRaw, ']')
-							keya = keyRaw[openIdx+1 : closeIdx]
+							if closeIdx == -1 {
+								err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+							} else {
+								keya = keyRaw[openIdx+1 : closeIdx]
+							}
 						}
 						q[keya] = valRaw
 					}
 				}
 			}
 		}
+		if err != nil {
+			return nil, err
+		}
 		payload := NewMethodQueryMapStringArrayStringPayload(q)
 
 		return payload, nil
@@ -1976,7 +2020,11 @@ func DecodeMethodQueryMapStringArrayStringValidateRequest(mux goahttp.Muxer, dec
 					{
 						openIdx := strings.IndexRune(keyRaw, '[')
 						closeIdx := strings.IndexRune(keyRaw, ']')
-						keya = keyRaw[openIdx+1 : closeIdx]
+						if closeIdx == -1 {
+							err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+						} else {
+							keya = keyRaw[openIdx+1 : closeIdx]
+						}
 					}
 					q[keya] = valRaw
 				}
@@ -2024,7 +2072,11 @@ func DecodeMethodQueryMapStringArrayBoolRequest(mux goahttp.Muxer, decoder func(
 						{
 							openIdx := strings.IndexRune(keyRaw, '[')
 							closeIdx := strings.IndexRune(keyRaw, ']')
-							keya = keyRaw[openIdx+1 : closeIdx]
+							if closeIdx == -1 {
+								err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+							} else {
+								keya = keyRaw[openIdx+1 : closeIdx]
+							}
 						}
 						var val []bool
 						{
@@ -2075,7 +2127,11 @@ func DecodeMethodQueryMapStringArrayBoolValidateRequest(mux goahttp.Muxer, decod
 					{
 						openIdx := strings.IndexRune(keyRaw, '[')
 						closeIdx := strings.IndexRune(keyRaw, ']')
-						keya = keyRaw[openIdx+1 : closeIdx]
+						if closeIdx == -1 {
+							err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+						} else {
+							keya = keyRaw[openIdx+1 : closeIdx]
+						}
 					}
 					var val []bool
 					{
@@ -2134,12 +2190,16 @@ func DecodeMethodQueryMapBoolArrayStringRequest(mux goahttp.Muxer, decoder func(
 						{
 							openIdx := strings.IndexRune(keyRaw, '[')
 							closeIdx := strings.IndexRune(keyRaw, ']')
-							keyaRaw := keyRaw[openIdx+1 : closeIdx]
-							v, err2 := strconv.ParseBool(keyaRaw)
-							if err2 != nil {
-								err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "boolean"))
+							if closeIdx == -1 {
+								err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+							} else {
+								keyaRaw := keyRaw[openIdx+1 : closeIdx]
+								v, err2 := strconv.ParseBool(keyaRaw)
+								if err2 != nil {
+									err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "boolean"))
+								}
+								keya = v
 							}
-							keya = v
 						}
 						q[keya] = valRaw
 					}
@@ -2177,12 +2237,16 @@ func DecodeMethodQueryMapBoolArrayStringValidateRequest(mux goahttp.Muxer, decod
 						{
 							openIdx := strings.IndexRune(keyRaw, '[')
 							closeIdx := strings.IndexRune(keyRaw, ']')
-							keyaRaw := keyRaw[openIdx+1 : closeIdx]
-							v, err2 := strconv.ParseBool(keyaRaw)
-							if err2 != nil {
-								err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "boolean"))
+							if closeIdx == -1 {
+								err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+							} else {
+								keyaRaw := keyRaw[openIdx+1 : closeIdx]
+								v, err2 := strconv.ParseBool(keyaRaw)
+								if err2 != nil {
+									err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "boolean"))
+								}
+								keya = v
 							}
-							keya = v
 						}
 						q[keya] = valRaw
 					}
@@ -2230,12 +2294,16 @@ func DecodeMethodQueryMapBoolArrayBoolRequest(mux goahttp.Muxer, decoder func(*h
 						{
 							openIdx := strings.IndexRune(keyRaw, '[')
 							closeIdx := strings.IndexRune(keyRaw, ']')
-							keyaRaw := keyRaw[openIdx+1 : closeIdx]
-							v, err2 := strconv.ParseBool(keyaRaw)
-							if err2 != nil {
-								err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "boolean"))
+							if closeIdx == -1 {
+								err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+							} else {
+								keyaRaw := keyRaw[openIdx+1 : closeIdx]
+								v, err2 := strconv.ParseBool(keyaRaw)
+								if err2 != nil {
+									err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "boolean"))
+								}
+								keya = v
 							}
-							keya = v
 						}
 						var val []bool
 						{
@@ -2286,12 +2354,16 @@ func DecodeMethodQueryMapBoolArrayBoolValidateRequest(mux goahttp.Muxer, decoder
 					{
 						openIdx := strings.IndexRune(keyRaw, '[')
 						closeIdx := strings.IndexRune(keyRaw, ']')
-						keyaRaw := keyRaw[openIdx+1 : closeIdx]
-						v, err2 := strconv.ParseBool(keyaRaw)
-						if err2 != nil {
-							err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "boolean"))
+						if closeIdx == -1 {
+							err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+						} else {
+							keyaRaw := keyRaw[openIdx+1 : closeIdx]
+							v, err2 := strconv.ParseBool(keyaRaw)
+							if err2 != nil {
+								err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "boolean"))
+							}
+							keya = v
 						}
-						keya = v
 					}
 					var val []bool
 					{
@@ -2484,7 +2556,11 @@ func DecodeMethodQueryPrimitiveMapStringArrayStringValidateRequest(mux goahttp.M
 					{
 						openIdx := strings.IndexRune(keyRaw, '[')
 						closeIdx := strings.IndexRune(keyRaw, ']')
-						keya = keyRaw[openIdx+1 : closeIdx]
+						if closeIdx == -1 {
+							err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+						} else {
+							keya = keyRaw[openIdx+1 : closeIdx]
+						}
 					}
 					q[keya] = valRaw
 				}
@@ -2535,7 +2611,11 @@ func DecodeMethodQueryPrimitiveMapStringBoolValidateRequest(mux goahttp.Muxer, d
 					{
 						openIdx := strings.IndexRune(keyRaw, '[')
 						closeIdx := strings.IndexRune(keyRaw, ']')
-						keya = keyRaw[openIdx+1 : closeIdx]
+						if closeIdx == -1 {
+							err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+						} else {
+							keya = keyRaw[openIdx+1 : closeIdx]
+						}
 					}
 					var vala bool
 					{
@@ -2592,12 +2672,16 @@ func DecodeMethodQueryPrimitiveMapBoolArrayBoolValidateRequest(mux goahttp.Muxer
 					{
 						openIdx := strings.IndexRune(keyRaw, '[')
 						closeIdx := strings.IndexRune(keyRaw, ']')
-						keyaRaw := keyRaw[openIdx+1 : closeIdx]
-						v, err2 := strconv.ParseBool(keyaRaw)
-						if err2 != nil {
-							err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "boolean"))
+						if closeIdx == -1 {
+							err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+						} else {
+							keyaRaw := keyRaw[openIdx+1 : closeIdx]
+							v, err2 := strconv.ParseBool(keyaRaw)
+							if err2 != nil {
+								err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "boolean"))
+							}
+							keya = v
 						}
-						keya = v
 					}
 					var val []bool
 					{
@@ -2663,8 +2747,12 @@ func DecodeMethodQueryMapStringMapIntStringValidateRequest(mux goahttp.Muxer, de
 					{
 						openIdx := strings.IndexRune(keyRaw, '[')
 						closeIdx := strings.IndexRune(keyRaw, ']')
-						keya = keyRaw[openIdx+1 : closeIdx]
-						keyRaw = keyRaw[closeIdx+1:]
+						if closeIdx == -1 {
+							err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+						} else {
+							keya = keyRaw[openIdx+1 : closeIdx]
+							keyRaw = keyRaw[closeIdx+1:]
+						}
 					}
 					if q[keya] == nil {
 						q[keya] = make(map[int]string)
@@ -2673,12 +2761,16 @@ func DecodeMethodQueryMapStringMapIntStringValidateRequest(mux goahttp.Muxer, de
 					{
 						openIdx := strings.IndexRune(keyRaw, '[')
 						closeIdx := strings.IndexRune(keyRaw, ']')
-						keybRaw := keyRaw[openIdx+1 : closeIdx]
-						v, err2 := strconv.ParseInt(keybRaw, 10, strconv.IntSize)
-						if err2 != nil {
-							err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keybRaw, "integer"))
+						if closeIdx == -1 {
+							err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+						} else {
+							keybRaw := keyRaw[openIdx+1 : closeIdx]
+							v, err2 := strconv.ParseInt(keybRaw, 10, strconv.IntSize)
+							if err2 != nil {
+								err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keybRaw, "integer"))
+							}
+							keyb = int(v)
 						}
-						keyb = int(v)
 					}
 					q[keya][keyb] = valRaw[0]
 				}
@@ -2722,13 +2814,17 @@ func DecodeMethodQueryMapIntMapStringArrayIntValidateRequest(mux goahttp.Muxer,
 					{
 						openIdx := strings.IndexRune(keyRaw, '[')
 						closeIdx := strings.IndexRune(keyRaw, ']')
-						keyaRaw := keyRaw[openIdx+1 : closeIdx]
-						v, err2 := strconv.ParseInt(keyaRaw, 10, strconv.IntSize)
-						if err2 != nil {
-							err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "integer"))
+						if closeIdx == -1 {
+							err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+						} else {
+							keyaRaw := keyRaw[openIdx+1 : closeIdx]
+							v, err2 := strconv.ParseInt(keyaRaw, 10, strconv.IntSize)
+							if err2 != nil {
+								err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "integer"))
+							}
+							keya = int(v)
+							keyRaw = keyRaw[closeIdx+1:]
 						}
-						keya = int(v)
-						keyRaw = keyRaw[closeIdx+1:]
 					}
 					if q[keya] == nil {
 						q[keya] = make(map[string][]int)
@@ -2737,7 +2833,11 @@ func DecodeMethodQueryMapIntMapStringArrayIntValidateRequest(mux goahttp.Muxer,
 					{
 						openIdx := strings.IndexRune(keyRaw, '[')
 						closeIdx := strings.IndexRune(keyRaw, ']')
-						keyb = keyRaw[openIdx+1 : closeIdx]
+						if closeIdx == -1 {
+							err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+						} else {
+							keyb = keyRaw[openIdx+1 : closeIdx]
+						}
 					}
 					var val []int
 					{
@@ -4807,7 +4907,11 @@ func DecodeMapQueryPrimitivePrimitiveRequest(mux goahttp.Muxer, decoder func(*ht
 					{
 						openIdx := strings.IndexRune(keyRaw, '[')
 						closeIdx := strings.IndexRune(keyRaw, ']')
-						keya = keyRaw[openIdx+1 : closeIdx]
+						if closeIdx == -1 {
+							err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+						} else {
+							keya = keyRaw[openIdx+1 : closeIdx]
+						}
 					}
 					query[keya] = valRaw[0]
 				}
@@ -4845,7 +4949,11 @@ func DecodeMapQueryPrimitiveArrayRequest(mux goahttp.Muxer, decoder func(*http.R
 					{
 						openIdx := strings.IndexRune(keyRaw, '[')
 						closeIdx := strings.IndexRune(keyRaw, ']')
-						keya = keyRaw[openIdx+1 : closeIdx]
+						if closeIdx == -1 {
+							err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+						} else {
+							keya = keyRaw[openIdx+1 : closeIdx]
+						}
 					}
 					var val []uint
 					{
@@ -5272,12 +5380,16 @@ func DecodeMethodARequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp
 						{
 							openIdx := strings.IndexRune(keyRaw, '[')
 							closeIdx := strings.IndexRune(keyRaw, ']')
-							keyaRaw := keyRaw[openIdx+1 : closeIdx]
-							v, err2 := strconv.ParseFloat(keyaRaw, 32)
-							if err2 != nil {
-								err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "float"))
+							if closeIdx == -1 {
+								err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+							} else {
+								keyaRaw := keyRaw[openIdx+1 : closeIdx]
+								v, err2 := strconv.ParseFloat(keyaRaw, 32)
+								if err2 != nil {
+									err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "float"))
+								}
+								keya = float32(v)
 							}
-							keya = float32(v)
 						}
 						var vala bool
 						{
@@ -5323,12 +5435,16 @@ func DecodeMethodARequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp
 						{
 							openIdx := strings.IndexRune(keyRaw, '[')
 							closeIdx := strings.IndexRune(keyRaw, ']')
-							keyaRaw := keyRaw[openIdx+1 : closeIdx]
-							v, err2 := strconv.ParseFloat(keyaRaw, 32)
-							if err2 != nil {
-								err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "float"))
+							if closeIdx == -1 {
+								err = goa.MergeErrors(err, goa.DecodePayloadError("invalid query string: missing closing bracket"))
+							} else {
+								keyaRaw := keyRaw[openIdx+1 : closeIdx]
+								v, err2 := strconv.ParseFloat(keyaRaw, 32)
+								if err2 != nil {
+									err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "float"))
+								}
+								keya = float32(v)
 							}
-							keya = float32(v)
 						}
 						var vala bool
 						{