--- title: "bracketeer Error Catalog" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{bracketeer Error Catalog} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = FALSE ) ``` ```{r setup} library(bracketeer) ``` This catalog lists common errors with likely causes and direct fixes. Errors include actionable identifiers (stage IDs, match IDs, participant counts) wherever possible. --- ## 1) Infeasible transition count **Symptom:** `validate()` or `build()` fails because the selector would pick more participants than are available from the source stage. ```{r} my_spec <- spec() |> round_robin("groups") |> single_elim("finals", take = top_n(8)) validate(my_spec, n = 6) # Error: stage 'finals' requires 8 participants via `top_n(8)` but source # stage 'groups' can produce at most 6. Adjust the selector or increase # participant count (currently n = 6). ``` **Fix:** - Reduce `n` in `top_n(n)` to fit the available pool, or - increase the participant count passed to `validate()` / `build()`. --- ## 2) `top_per_group()` on a non-grouped stage **Symptom:** Error when a per-group selector is used on a stage without group structure. ```{r} trn <- tournament(paste("Team", 1:8)) |> round_robin("league") |> single_elim("playoffs", take = top_per_group(2)) # Error: `top_per_group()` requires the source stage 'league' to have # groups, but it was defined without `groups =`. Use `top_n()` for flat # standings, or add `groups =` to the source stage. ``` **Fix:** - Use `top_n(n)` if the source stage is a flat round-robin, or - add `groups = k` to the source stage verb if group play is intended. --- ## 3) `previous_stage()` on the first stage **Symptom:** Error when the first stage verb implicitly or explicitly uses `previous_stage()` but there is no preceding stage. ```{r} spec() |> single_elim("finals", from = previous_stage()) # Error: `previous_stage()` in stage 'finals' resolved to no prior stage. # 'finals' is the first stage in this spec. Provide an explicit `from =` # or add a source stage before it. ``` **Fix:** This only happens if you set `from = previous_stage()` explicitly on the first stage, or if you call a stage verb on an empty spec without a source. Add the source stage first: ```{r} spec() |> round_robin("groups") |> single_elim("finals", take = top_n(8)) # from = previous_stage() is implicit, resolves to "groups" ``` --- ## 4) Explicit `from =` stage ID not found **Symptom:** Error when a `from =` argument references a stage that does not exist. ```{r} tournament(paste("Team", 1:16)) |> round_robin("groups") |> single_elim("finals", from = "typo_stage", take = top_n(8)) # Error: `from = "typo_stage"` in stage 'finals' references a stage that # does not exist. Known stages: groups. Check the stage ID spelling. ``` **Fix:** Check the stage ID spelling. Use the exact string passed to the source stage verb. --- ## 5) Overlapping selectors in a branch **Symptom:** Two stages branching from the same source both select the same participants, causing a conflict. ```{r} tournament(paste("Team", 1:16)) |> round_robin("groups") |> single_elim("championship", from = "groups", take = top_n(8)) |> single_elim("consolation", from = "groups", take = top_n(8)) # same 8! # Error: stages 'championship' and 'consolation' both consume overlapping # participants from source 'groups'. Use `remaining()` for the second # branch to select the leftover pool, or adjust selectors to be disjoint. ``` **Fix:** Use `remaining()` for the second branch: ```{r} tournament(paste("Team", 1:16)) |> round_robin("groups") |> single_elim("championship", from = "groups", take = top_n(8)) |> single_elim("consolation", from = "groups", take = remaining()) ``` --- ## 6) Overwrite blocked by downstream materialization **Symptom:** Attempting to change a result after a downstream stage has already been materialized from it. ```{r} # After all group results have been entered and "knockout" has materialized: trn <- trn |> result("groups", match = 1, score = c(0, 2)) # Error: result for match 1 in stage 'groups' cannot be overwritten because # downstream stage 'knockout' has already been materialized from 'groups'. # Use teardown(trn, "knockout") first to unlock result editing. ``` **Fix:** Use `teardown()` to un-materialize the blocking downstream stage, then re-enter the corrected result: ```{r} trn <- teardown(trn, "knockout") trn <- trn |> result("groups", match = 1, score = c(0, 2)) # "knockout" will re-materialize automatically when groups is complete again. ``` --- ## 7) `validate()` fails for duplicate stage IDs **Symptom:** Two stage verbs use the same stage ID. ```{r} spec() |> round_robin("stage") |> single_elim("stage") # duplicate! # Error: stage ID 'stage' is already registered. Stage IDs must be unique. # Provide a distinct ID for each stage. ``` **Fix:** Use unique IDs for every stage. --- ## 8) Invalid `score` argument **Symptom:** `result()` receives a score that is not a numeric vector of at least length 2. ```{r} trn <- trn |> result("groups", match = 1, score = 2) # Error: `score` must be a numeric vector of length >= 2 (e.g., c(2, 1)). # Received: a single value (2). Did you mean score = c(2, 1)? ``` **Fix:** Always pass `score` as a vector: `score = c(home_score, away_score)`. --- ## Operational checklist 1. Define: `tournament(teams) |> `. 2. (Optional) Validate: `validate(spec, n)` before building. 3. Inspect schedule: `matches(trn, stage)`, `stage_status(trn)`. 4. Enter results: `result(trn, stage, match, score = c(x, y))`. 5. Auto-advance is the default — check `stage_status(trn)` to confirm. 6. Use `teardown(trn, stage)` if you need to correct results after advancement. 7. Finish: `winner(trn)`, `rankings(trn)`, `routing_log(trn)`.