{"record":{"id":"1f58f49be6f0b965","repo":"mattermost-community/focalboard","slug":"getblockhistorynewestchildren-unable-to-generate-s-1f58f4","errorCode":null,"errorMessage":"getBlockHistoryNewestChildren unable to generate sql: %w","messagePattern":"getBlockHistoryNewestChildren unable to generate sql: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/services/store/sqlstore/blocks.go","lineNumber":712,"sourceCode":"\t}\n\n\tquery := s.getQueryBuilder(db).\n\t\tSelect(s.blockFields(\"bh\")...).\n\t\tFrom(s.tablePrefix+\"blocks_history AS bh\").\n\t\tInnerJoin(\"(\"+subQuery+\") AS sub ON bh.id=sub.id AND bh.insert_at=sub.max_insert_at\", subArgs...)\n\n\tif opts.Page != 0 {\n\t\tquery = query.Offset(uint64(opts.Page * opts.PerPage))\n\t}\n\n\tif opts.PerPage > 0 {\n\t\t// limit+1 to detect if more records available\n\t\tquery = query.Limit(uint64(opts.PerPage + 1))\n\t}\n\n\tsql, args, err := query.ToSql()\n\tif err != nil {\n\t\treturn nil, false, fmt.Errorf(\"getBlockHistoryNewestChildren unable to generate sql: %w\", err)\n\t}\n\n\t// if we're using postgres or sqlite, we need to replace the\n\t// question mark placeholder with the numbered dollar one, now\n\t// that the full query is built\n\tif s.dbType == model.PostgresDBType || s.dbType == model.SqliteDBType {\n\t\tvar rErr error\n\t\tsql, rErr = sq.Dollar.ReplacePlaceholders(sql)\n\t\tif rErr != nil {\n\t\t\treturn nil, false, fmt.Errorf(\"getBlockHistoryNewestChildren unable to replace sql placeholders: %w\", rErr)\n\t\t}\n\t}\n\n\trows, err := db.Query(sql, args...)\n\tif err != nil {\n\t\ts.logger.Error(`getBlockHistoryNewestChildren ERROR`, mlog.Err(err))\n\t\treturn nil, false, err\n\t}","sourceCodeStart":694,"sourceCodeEnd":730,"githubUrl":"https://github.com/mattermost-community/focalboard/blob/a84bbb65e32edf972856b329417096ac413518e9/server/services/store/sqlstore/blocks.go#L694-L730","documentation":"The final (outer) history query failed at squirrel's ToSql() stage, so no SQL string could be generated for the blocks_history join query. Like error 92 but on the main query instead of the subquery; it is returned before any database round trip.","triggerScenarios":"GetBlockHistoryNewestChildren with opts that make the outer query unrenderable — typically PerPage<=0 leading to query.Limit(uint64(opts.PerPage+1)) with an invalid/negative limit, or a ToSql compilation error in the joined select.","commonSituations":"Callers computing PerPage dynamically and passing 0 or negative values; code changes to the main query leaving mismatched placeholders; dialect-specific builder regressions.","solutions":["Inspect the wrapped err for the exact squirrel failure","Validate opts.PerPage is > 0 before calling (or that the store clamps it)","If building limits yourself, ensure uint64 conversion doesn't wrap a negative value","Check for recent modifications to the query construction (Select/Join/Limit order)"],"exampleFix":"// before\nopts.PerPage = 0 // becomes Limit(1)? or invalid\nhist, _, err := store.GetBlockHistoryNewestChildren(id, opts)\n// after\nif opts.PerPage <= 0 {\n    opts.PerPage = store.BlockHistoryDefaultPerPage\n}\nhist, _, err := store.GetBlockHistoryNewestChildren(id, opts)","handlingStrategy":"validation","validationCode":"if opts.PerPage <= 0 {\n    opts.PerPage = store.BlockHistoryDefaultPerPage\n}\n// then call GetBlockHistoryNewestChildren","typeGuard":null,"tryCatchPattern":"hist, hasMore, err := store.GetBlockHistoryNewestChildren(blockID, opts)\nif err != nil && strings.Contains(err.Error(), \"unable to generate sql\") {\n    log.Printf(\"history query build failed for %s: %v\", blockID, err)\n    return fallbackHistoryFetch(blockID, opts)\n}","preventionTips":["Validate PerPage before calling; remember the store computes Limit(PerPage+1) with a uint64 cast","Avoid negative ints that wrap around on uint64 conversion","Keep query-construction code unchanged unless you test all dialects","Cover history queries with unit tests for each db type"],"tags":["sql","query-builder","history"],"backgroundTag":"sql-generation-failed","analyzedSha":"a84bbb65e32edf972856b329417096ac413518e9","analyzedAt":"2026-08-30T09:22:20.720Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}