mattermost-community/focalboard · error

getBlockHistoryNewestChildren unable to generate subquery: %

Error message

getBlockHistoryNewestChildren unable to generate subquery: %w

What it means

getBlockHistoryNewestChildren builds a subquery (max insert_at per block id) with squirrel; if sub.ToSql() fails to compile the SQL, this wrapped error is returned. It indicates the query builder could not render the constructed subquery, typically due to malformed clauses or empty/mismatched arguments.

Source

Thrown at server/services/store/sqlstore/blocks.go:693

	builder := s.getQueryBuilder(db).PlaceholderFormat(sq.Question)

	sub := builder.
		Select("bh2.id", "MAX(bh2.insert_at) AS max_insert_at").
		From(s.tablePrefix + "blocks_history AS bh2").
		Where(sq.Eq{"bh2.parent_id": parentID}).
		GroupBy("bh2.id")

	if opts.AfterUpdateAt != 0 {
		sub = sub.Where(sq.Gt{"bh2.update_at": opts.AfterUpdateAt})
	}

	if opts.BeforeUpdateAt != 0 {
		sub = sub.Where(sq.Lt{"bh2.update_at": opts.BeforeUpdateAt})
	}

	subQuery, subArgs, err := sub.ToSql()
	if err != nil {
		return nil, false, fmt.Errorf("getBlockHistoryNewestChildren unable to generate subquery: %w", err)
	}

	query := s.getQueryBuilder(db).
		Select(s.blockFields("bh")...).
		From(s.tablePrefix+"blocks_history AS bh").
		InnerJoin("("+subQuery+") AS sub ON bh.id=sub.id AND bh.insert_at=sub.max_insert_at", subArgs...)

	if opts.Page != 0 {
		query = query.Offset(uint64(opts.Page * opts.PerPage))
	}

	if opts.PerPage > 0 {
		// limit+1 to detect if more records available
		query = query.Limit(uint64(opts.PerPage + 1))
	}

	sql, args, err := query.ToSql()
	if err != nil {

View on GitHub (pinned to a84bbb65e3)

Solutions

  1. Check the wrapped err (%w) for the squirrel ToSql failure detail
  2. Verify the opts passed to GetBlockHistoryNewestChildren are sane (non-negative PerPage, valid timestamps)
  3. If you modified the subquery construction, confirm every Where/Select clause is well-formed and args align with placeholders
  4. Report/patch upstream if a specific opts combination reliably breaks ToSql

Example fix

// before
opts := store.BlockHistoryOpts{PerPage: -1}
hist, hasMore, err := store.GetBlockHistoryNewestChildren(blockID, opts)
// after
if opts.PerPage < 0 {
    opts.PerPage = store.BlockHistoryDefaultPerPage
}
hist, hasMore, err := store.GetBlockHistoryNewestChildren(blockID, opts)
Defensive patterns

Strategy: validation

Validate before calling

func safeHistoryOpts(opts store.BlockHistoryOpts) store.BlockHistoryOpts {
    if opts.PerPage <= 0 {
        opts.PerPage = 25
    }
    return opts
}

Try / catch

hist, hasMore, err := store.GetBlockHistoryNewestChildren(blockID, opts)
if err != nil {
    if strings.Contains(err.Error(), "unable to generate subquery") {
        return nil, fmt.Errorf("bad history opts %v: %w", opts, err)
    }
    return nil, err
}

Prevention

When it happens

Trigger: GetBlockHistoryNewestChildren invoked with option combinations that produce an unrenderable subquery — e.g. malformed opts fields (BeforeUpdateAt/AfterUpdateAt/PerPage handling) causing squirrel ToSql() to error.

Common situations: Programmatic callers passing inconsistent pagination/filter options; regressions after modifying the query-building code; unusual DB dialect setups interfering with clause construction.

Related errors


AI-assisted analysis of mattermost-community/focalboard@a84bbb65e3 (2026-08-30). Data as JSON: /api/errors/e3baa09d07bcc4d0. Report an issue: GitHub.