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.
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
nintop_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.
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 = kto 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.
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:
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.
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.
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:
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.
# 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:
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.
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.
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
- Define:
tournament(teams) |> <stage_verbs>. - (Optional) Validate:
validate(spec, n)before building. - Inspect schedule:
matches(trn, stage),stage_status(trn). - Enter results:
result(trn, stage, match, score = c(x, y)). - Auto-advance is the default — check
stage_status(trn)to confirm. - Use
teardown(trn, stage)if you need to correct results after advancement. - Finish:
winner(trn),rankings(trn),routing_log(trn).
