wavetermdev/waveterm · error
too many iterations looking for tab in block parents
Error message
too many iterations looking for tab in block parents
What it means
DBFindTabForBlockId walks the parent chain of blocks (block -> parent oref -> ...) up to 5 hops to find the enclosing tab. If it has not reached a tab after 5 iterations it gives up with this error, protecting against cycles or unexpectedly deep block nesting in the layout tree.
Source
Thrown at pkg/wstore/wstore_dbops.go:369
if err != nil {
return err
}
return WithTx(ctx, func(tx *TxWrap) error {
table := waveObjTableName(val)
waveobj.SetVersion(val, 1)
query := fmt.Sprintf("INSERT INTO %s (oid, version, data) VALUES (?, ?, ?)", table)
tx.Exec(query, oid, 1, jsonData)
waveobj.ContextAddUpdate(ctx, waveobj.WaveObjUpdate{UpdateType: waveobj.UpdateType_Update, OType: val.GetOType(), OID: oid, Obj: val})
return nil
})
}
func DBFindTabForBlockId(ctx context.Context, blockId string) (string, error) {
return WithTxRtn(ctx, func(tx *TxWrap) (string, error) {
iterNum := 1
for {
if iterNum > 5 {
return "", fmt.Errorf("too many iterations looking for tab in block parents")
}
query := `
SELECT json_extract(b.data, '$.parentoref') AS parentoref
FROM db_block b
WHERE b.oid = ?;`
parentORef := tx.GetString(query, blockId)
oref, err := waveobj.ParseORef(parentORef)
if err != nil {
return "", fmt.Errorf("bad block parent oref: %v", err)
}
if oref.OType == "tab" {
return oref.OID, nil
}
if oref.OType == "block" {
blockId = oref.OID
iterNum++
continue
}View on GitHub (pinned to a4447c1563)
Solutions
- Inspect the block's parent chain (db_block.parentoref values) for cycles or excessive depth and repair the layout
- Re-create or flatten the offending nested layout so the tab is within 5 levels
- Verify blockId is valid and the chain terminates at a tab, not another container type
Defensive patterns
Strategy: try-catch
Try / catch
tabId, err := wstore.DBFindTabForBlockId(ctx, blockId)
if err != nil {
if strings.Contains(err.Error(), "too many iterations") {
// fall back to workspace-level lookup or rebuild layout
}
return err
} Prevention
- Avoid nesting blocks more than a few levels deep
- Watch for cyclic parentoref assignments when building custom layouts
- Log the parent chain when traversal fails to spot corruption
When it happens
Trigger: Passing a blockId whose parent chain is longer than 5 block levels, a cyclic parentoref layout, or a corrupted block row whose parent points back into the same block tree indefinitely.
Common situations: Deeply nested split/pane layouts created programmatically; corrupted waveai/state DB rows with self-referential parent orefs; calling the function with a root-level block whose chain never terminates in a tab.
Related errors
- Invalid node
- Invalid direction: ${direction}
- Invalid InsertOperation
- too many flush errors (clearing entry): %w
- opening db: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/9607711728b314eb.
Report an issue: GitHub.