{"record":{"id":"287a9be159d51bda","repo":"bytebase/bytebase","slug":"unsupported-order-field-q","errorCode":null,"errorMessage":"unsupported order field %q","messagePattern":"unsupported order field %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/store/common.go","lineNumber":58,"sourceCode":"// mapping API field names to SQL columns. Strict where parseOrderBy is not:\n// every comma-separated entry must be a whitelisted field with an optional\n// \"asc\"/\"desc\" suffix, and a repeated field is rejected — malformed input\n// errors instead of being silently reinterpreted.\nfunc getOrderByKeys(orderBy string, columns map[string]string) ([]*OrderByKey, error) {\n\tif orderBy == \"\" {\n\t\treturn nil, nil\n\t}\n\n\tvar result []*OrderByKey\n\tseen := make(map[string]bool)\n\tfor entry := range strings.SplitSeq(orderBy, \",\") {\n\t\tparts := strings.Fields(entry)\n\t\tif len(parts) == 0 || len(parts) > 2 {\n\t\t\treturn nil, errors.Errorf(\"invalid order_by entry %q\", strings.TrimSpace(entry))\n\t\t}\n\t\tcolumn, ok := columns[parts[0]]\n\t\tif !ok {\n\t\t\treturn nil, errors.Errorf(\"unsupported order field %q\", parts[0])\n\t\t}\n\t\tif seen[parts[0]] {\n\t\t\treturn nil, errors.Errorf(\"duplicate order field %q\", parts[0])\n\t\t}\n\t\tseen[parts[0]] = true\n\t\tsortOrder := ASC\n\t\tif len(parts) == 2 {\n\t\t\tswitch parts[1] {\n\t\t\tcase \"asc\":\n\t\t\tcase \"desc\":\n\t\t\t\tsortOrder = DESC\n\t\t\tdefault:\n\t\t\t\treturn nil, errors.Errorf(\"invalid order direction %q, expect asc or desc\", parts[1])\n\t\t\t}\n\t\t}\n\t\tresult = append(result, &OrderByKey{Key: column, SortOrder: sortOrder})\n\t}\n\treturn result, nil","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/store/common.go#L40-L76","documentation":"getOrderByKeys parses an AIP-132 order_by string against a whitelist of allowed column names (columns map) and returns a SQL ORDER BY key list. This error is thrown when a field name in the order_by string is not present in the caller-provided whitelist, e.g. GetSavedQueryOrders for saved queries. It prevents building ORDER BY clauses from arbitrary user input.","triggerScenarios":"Calling GetSavedQueryOrders (or any getOrderByKeys caller) with an order_by string containing a field not in the columns map, e.g. order_by=\"created_at desc\" when only \"create_time\" is allowed, a typo like \"nmae\", or a raw column name instead of the API field name.","commonSituations":"Client code copying field names from another resource's list API, hand-writing order_by strings instead of using generated AIP-132 helpers, or API drift after a field was renamed/removed from the allowed columns.","solutions":["Check the columns whitelist in the calling Get*Orders function and use exactly those field names in order_by","Fix typos and use the AIP-132 snake_case API field name, not the SQL column name","If the field should be sortable, add it to the columns map in the caller"],"exampleFix":"// before\norder_by = \"created_time desc\"\n// after\norder_by = \"create_time desc\"","handlingStrategy":"validation","validationCode":"allowed := []string{\"create_time\", \"update_time\", \"name\"} // check the Get*Orders whitelist\nfor _, f := range strings.FieldsFunc(orderBy, func(r rune) bool { return r == ',' }) {\n    parts := strings.Fields(strings.TrimSpace(f))\n    if len(parts) == 0 || !slices.Contains(allowed, parts[0]) {\n        return fmt.Errorf(\"unsupported order field %q\", parts)\n    }\n}","typeGuard":null,"tryCatchPattern":"keys, err := store.GetSavedQueryOrders(ctx, orderBy)\nif err != nil {\n    var cerr *common.Error\n    if errors.As(err, &cerr) || strings.Contains(err.Error(), \"unsupported order field\") {\n        orderBy = \"\" // fall back to default order\n        keys, err = store.GetSavedQueryOrders(ctx, orderBy)\n    }\n    if err != nil { return err }\n}","preventionTips":["Generate order_by strings from the same columns whitelist the store uses","Write a client-side test asserting every order_by value your app sends parses successfully","Never map API field names to SQL columns by hand in client code"],"tags":["sql","order-by","validation","aip-132"],"backgroundTag":"invalid-enum-value","analyzedSha":"1870550677fe08f0d2a78c07acd27541464eb945","analyzedAt":"2026-09-06T21:16:13.665Z","contentChangedAt":"2026-09-06T21:16:13.665Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}