{"record":{"id":"979f517275e47157","repo":"pocketbase/pocketbase","slug":"unknown-modifier-in-q","errorCode":null,"errorMessage":"unknown modifier in %q","messagePattern":"unknown modifier in %q","errorType":"exception","errorClass":null,"httpStatus":400,"severity":"error","filePath":"core/record_field_resolver.go","lineNumber":591,"sourceCode":"\nfunc splitModifier(combined string) (string, string, error) {\n\tparts := strings.Split(combined, \":\")\n\n\tif len(parts) != 2 {\n\t\treturn combined, \"\", nil\n\t}\n\n\t// validate modifier\n\tswitch parts[1] {\n\tcase issetModifier,\n\t\teachModifier,\n\t\tlengthModifier,\n\t\tlowerModifier,\n\t\tchangedModifier:\n\t\treturn parts[0], parts[1], nil\n\t}\n\n\treturn \"\", \"\", fmt.Errorf(\"unknown modifier in %q\", combined)\n}\n","sourceCodeStart":573,"sourceCodeEnd":593,"githubUrl":"https://github.com/pocketbase/pocketbase/blob/5d217ddb50cb144d80a5d0b0bdf11b52b2c3e457/core/record_field_resolver.go#L573-L593","documentation":"The field/modifier parser split the token on ':' and the modifier part is not one of the five known modifiers (isset, each, length, lower, changed). The message echoes the full combined token. This is a syntax error in a filter/sort string, returned before any database work happens.","triggerScenarios":"Filter containing a token like \"title:upper\", \"date:format\", or a URL that turned '=' into a colon; also plain typos such as \"field: lengh\". Anything after ':' that is not in the allow-list triggers it.","commonSituations":"Assuming a modifier exists that doesn't (e.g. :upper, :trim); copy-pasting from docs of a different version; client-side filter builders that join field and operator with ':' by mistake.","solutions":["Locate the token named in the message and correct the modifier to one of: :isset, :each, :length, :lower, :changed.","If you wanted an uppercase comparison, invert it: compare LOWER(field) via field:lower against an already-lowercased value.","If the colon is accidental (e.g. time value '10:30' inside a field token), quote the value properly so it is not parsed as a modifier."],"exampleFix":"// before\nfilter := \"title:upper = 'ABC'\"\n// after\nfilter := \"title:lower = 'abc'\"","handlingStrategy":"validation","validationCode":"var knownModifiers = map[string]bool{\":isset\": true, \":each\": true, \":length\": true, \":lower\": true, \":changed\": true}\nfunc validateModifiers(filter string) error {\n    for _, tok := range strings.FieldsFunc(filter, func(r rune) bool { return r == ' ' || r == '(' || r == ')' }) {\n        if i := strings.Index(tok, \":\"); i > 0 && strings.ContainsAny(tok[i:], \"abcdefghijklmnopqrstuvwxyz\") {\n            mod := tok[i:]\n            if !knownModifiers[mod] {\n                return fmt.Errorf(\"unknown modifier %q in token %q\", mod, tok)\n            }\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Refer to the modifier allow-list (isset/each/length/lower/changed) when writing filters.","Lint generated filter strings before sending requests."],"tags":["filter","modifier","validation","api"],"backgroundTag":null,"analyzedSha":"5d217ddb50cb144d80a5d0b0bdf11b52b2c3e457","analyzedAt":"2026-08-15T10:06:33.165Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}