gastownhall/beads · error

expected value at position %d, got %s

Error message

expected value at position %d, got %s

What it means

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.

Source

Thrown at internal/query/parser.go:291

	// Value can be identifier, string, number, or duration
	var value string
	var valueType TokenType
	switch p.current.Type {
	case TokenIdent:
		value = p.current.Value
		valueType = TokenIdent
	case TokenString:
		value = p.current.Value
		valueType = TokenString
	case TokenNumber:
		value = p.current.Value
		valueType = TokenNumber
	case TokenDuration:
		value = p.current.Value
		valueType = TokenDuration
	default:
		return nil, fmt.Errorf("expected value at position %d, got %s", p.current.Pos, p.current.Type.String())
	}

	if err := p.advance(); err != nil {
		return nil, err
	}

	return &ComparisonNode{
		Field:     field,
		Op:        op,
		Value:     value,
		ValueType: valueType,
	}, nil
}

// Parse is a convenience function that parses a query string.
func Parse(input string) (Node, error) {
	p := NewParser(input)
	return p.Parse()

View on GitHub (pinned to 71377f2769)

Solutions

  1. Look at the reported position in your query string and supply a valid literal (number, string, duration) after the comparison operator
  2. Quote string values that contain spaces or special characters
  3. Remove or correct stray characters/keywords that cannot start a value
  4. Check the parser docs for the accepted literal grammar for the value position

Example fix

// before
bd query 'priority >'
// after
bd query 'priority > 2'
Defensive patterns

Strategy: validation

Validate before calling

// Validate the query has a literal after each operator before invoking the parser
func hasValueAfterOperator(q string) bool {
	parts := strings.Fields(q)
	for i, p := range parts {
		if isComparisonOp(p) && (i+1 >= len(parts) || !looksLikeLiteral(parts[i+1])) {
			return false
		}
	}
	return true
}

Try / catch

if _, err := parser.Parse(query); err != nil {
	var perr *ParseError
	if errors.As(err, &perr) {
		return fmt.Errorf("query syntax error at position %d: %w", perr.Pos, err)
	}
	return err
}

Prevention

When it happens

Trigger: 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 != ()`).

Common situations: 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.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/13a688df3cbdfcee. Report an issue: GitHub.