gastownhall/beads · error

empty query

Error message

empty query

What it means

Parser.Parse (internal/query/parser.go:110) found TokenEOF as the very first token, meaning the input query string was empty or contained only whitespace. The grammar requires at least one comparison or expression, so an empty query is rejected rather than returning a match-all node.

Source

Thrown at internal/query/parser.go:110

type Parser struct {
	lexer   *Lexer
	current Token
	peeked  *Token
}

// NewParser creates a new Parser for the given input.
func NewParser(input string) *Parser {
	return &Parser{lexer: NewLexer(input)}
}

// Parse parses the query string and returns the root AST node.
func (p *Parser) Parse() (Node, error) {
	if err := p.advance(); err != nil {
		return nil, err
	}

	if p.current.Type == TokenEOF {
		return nil, fmt.Errorf("empty query")
	}

	node, err := p.parseOr()
	if err != nil {
		return nil, err
	}

	if p.current.Type != TokenEOF {
		return nil, fmt.Errorf("unexpected token %q at position %d (expected end of query)", p.current.Value, p.current.Pos)
	}

	return node, nil
}

// advance moves to the next token.
func (p *Parser) advance() error {
	if p.peeked != nil {
		p.current = *p.peeked

View on GitHub (pinned to 71377f2769)

Solutions

  1. Provide a non-empty query, e.g. `status=open`.
  2. Guard the call site: if the query string is blank after TrimSpace, skip the query API entirely instead of parsing.
  3. In shell, use `${Q:?Q not set}` or default the query (`${Q:-status=open}`) before passing it.
  4. When building queries programmatically, default to a catch-all known field clause when no parts were added.

Example fix

// before
node, err := query.Parse(userQuery) // "" -> error
// after
if strings.TrimSpace(userQuery) == "" {
    return nil // or default query
}
node, err := query.Parse(userQuery)
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(q) == "" {
    return nil // skip query entirely or use a default
}

Try / catch

node, err := query.Parse(q)
if err != nil && err.Error() == "empty query" {
    return handleAll() // treat as no filter
}

Prevention

When it happens

Trigger: query.Parse("") or query.Parse(" "); a shell variable holding the query expanding to nothing (`bd list --query "$Q"` with Q unset); passing `--query ""` on the CLI; programmatic callers building a query from optional parts that all evaluated to empty.

Common situations: Unset or empty environment variables in scripts; CI configs with a blank query field; string builders that only append clauses inside conditionals and produce "" when no condition matched.

Related errors


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