{"record":{"id":"5450bd89cbb7e29f","repo":"usememos/memos","slug":"boolean-literal-required","errorCode":null,"errorMessage":"boolean literal required","messagePattern":"boolean literal required","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"internal/filter/render.go","lineNumber":862,"sourceCode":"\treturn r.addArg(v)\n}\n\nfunc expectLiteral(expr ValueExpr) (any, error) {\n\tlit, ok := expr.(*LiteralValue)\n\tif !ok {\n\t\treturn nil, errors.New(\"expression must be a literal\")\n\t}\n\treturn lit.Value, nil\n}\n\nfunc expectBool(expr ValueExpr) (bool, error) {\n\tlit, err := expectLiteral(expr)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tvalue, ok := lit.(bool)\n\tif !ok {\n\t\treturn false, errors.New(\"boolean literal required\")\n\t}\n\treturn value, nil\n}\n\nfunc expectNumericLiteral(expr ValueExpr) (int64, error) {\n\tlit, err := expectLiteral(expr)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn toInt64(lit)\n}\n\nfunc toInt64(value any) (int64, error) {\n\tswitch v := value.(type) {\n\tcase int:\n\t\treturn int64(v), nil\n\tcase int32:\n\t\treturn int64(v), nil","sourceCodeStart":844,"sourceCodeEnd":880,"githubUrl":"https://github.com/usememos/memos/blob/14d757ce1fb31c78590f374bc042f8dbedbc20d7/internal/filter/render.go#L844-L880","documentation":"Thrown by expectBool in the filter renderer when a boolean-only construct (e.g. `pinned` comparisons or boolean flags) receives a literal that is not a Go bool. The parser accepted it as a literal node, but the type assertion lit.(bool) failed, so the filter cannot be rendered to SQL.","triggerScenarios":"Filters like `pinned == \"true\"`, `pinned == 1`, or `pinned in [true, \"false\"]` where the boolean position gets a string or numeric literal.","commonSituations":"Frontends or scripts serializing booleans as strings (JSON query params), users quoting boolean values out of habit, or porting filters from a dialect where truthy coercion exists.","solutions":["Use bare boolean literals: `pinned == true` not `pinned == \"true\"`","Fix the client code that stringifies booleans before building filter strings","Validate filter strings against the engine (CompileToStatement) before saving them"],"exampleFix":"// before\nfilter := `pinned == \"true\"`\n// after\nfilter := `pinned == true`","handlingStrategy":"validation","validationCode":"// Ensure boolean positions get bare true/false, not quoted strings or numbers\nvar quotedBool = regexp.MustCompile(`==\\s*\"(?:true|false)\"`)\nfunc hasQuotedBoolean(filter string) bool { return quotedBool.MatchString(filter) }","typeGuard":"func isBoolLiteral(v any) bool { _, ok := v.(bool); return ok }","tryCatchPattern":"// Wrap compile; map 'boolean literal required' to a user-facing message with the offending fragment\nif _, err := engine.CompileToStatement(ctx, filter, opts); err != nil {\n  if strings.Contains(err.Error(), \"boolean literal required\") {\n    return errors.New(\"use bare true/false without quotes in the filter\")\n  }\n  return err\n}","preventionTips":["Never stringify booleans when constructing filters","Keep a shared filter-builder that emits typed literals","Test saved filters in a filter playground before use"],"tags":["filter","validation","boolean"],"backgroundTag":null,"analyzedSha":"14d757ce1fb31c78590f374bc042f8dbedbc20d7","analyzedAt":"2026-08-15T09:27:36.538Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}