{"record":{"id":"13a688df3cbdfcee","repo":"gastownhall/beads","slug":"expected-value-at-position-d-got-s","errorCode":null,"errorMessage":"expected value at position %d, got %s","messagePattern":"expected value at position (.+?), got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/query/parser.go","lineNumber":291,"sourceCode":"\n\t// Value can be identifier, string, number, or duration\n\tvar value string\n\tvar valueType TokenType\n\tswitch p.current.Type {\n\tcase TokenIdent:\n\t\tvalue = p.current.Value\n\t\tvalueType = TokenIdent\n\tcase TokenString:\n\t\tvalue = p.current.Value\n\t\tvalueType = TokenString\n\tcase TokenNumber:\n\t\tvalue = p.current.Value\n\t\tvalueType = TokenNumber\n\tcase TokenDuration:\n\t\tvalue = p.current.Value\n\t\tvalueType = TokenDuration\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"expected value at position %d, got %s\", p.current.Pos, p.current.Type.String())\n\t}\n\n\tif err := p.advance(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &ComparisonNode{\n\t\tField:     field,\n\t\tOp:        op,\n\t\tValue:     value,\n\t\tValueType: valueType,\n\t}, nil\n}\n\n// Parse is a convenience function that parses a query string.\nfunc Parse(input string) (Node, error) {\n\tp := NewParser(input)\n\treturn p.Parse()","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/query/parser.go#L273-L309","documentation":"The query parser's parseComparison reached a token that cannot start a value (number, string, duration, etc.) where a literal value was expected after a comparison operator. It reports the token position and the actual token type found so you can locate the malformed query input.","triggerScenarios":"Parsing a query where the comparison operator is followed by an unexpected token — e.g. a bare identifier in wrong case, a keyword, an operator, or end-of-input where a literal was required (like `priority >` or `status != ()`).","commonSituations":"Hand-written query strings with typos, missing quoted strings, values omitted after operators, pasted queries with non-ASCII quote characters, or a query language version change altering accepted literals.","solutions":["Look at the reported position in your query string and supply a valid literal (number, string, duration) after the comparison operator","Quote string values that contain spaces or special characters","Remove or correct stray characters/keywords that cannot start a value","Check the parser docs for the accepted literal grammar for the value position"],"exampleFix":"// before\nbd query 'priority >'\n// after\nbd query 'priority > 2'","handlingStrategy":"validation","validationCode":"// Validate the query has a literal after each operator before invoking the parser\nfunc hasValueAfterOperator(q string) bool {\n\tparts := strings.Fields(q)\n\tfor i, p := range parts {\n\t\tif isComparisonOp(p) && (i+1 >= len(parts) || !looksLikeLiteral(parts[i+1])) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}","typeGuard":null,"tryCatchPattern":"if _, err := parser.Parse(query); err != nil {\n\tvar perr *ParseError\n\tif errors.As(err, &perr) {\n\t\treturn fmt.Errorf(\"query syntax error at position %d: %w\", perr.Pos, err)\n\t}\n\treturn err\n}","preventionTips":["Quote string literals containing spaces or special characters","Always provide a value after comparison operators","Lint user-supplied queries before parsing","Keep queries simple; build them programmatically rather than by string concatenation"],"tags":["query","parser","syntax-error"],"backgroundTag":"query-syntax-error","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}