Home / Forum / Suggestions / I return to teams according to the second act.

I return to teams according to the second act.

Hello, I'm starting a new discussion on this topic for two reasons: the previous one was getting too long, and when there are multiple pages the forum places you at the first page instead of the last page where you can add a message, so you have to manually navigate to the end to write a new post. Also, for some reason, every time I reach the last page it asks me to log in again before I can write, and after logging in it brings me back to the Home! Good thing it's time to start a new thread.

I wanted to give you a fresh list of considerations that emerged from some difficulties during the registration for our last tournament; when you have time, take a look, and if needed I can elaborate on the reasons behind each request:


- “Add unpaired player” should allow registration only with Surname, without First Name.

- When typing some characters in “Add unpaired player” and players that match the filter appear, add the birth year (field “B-Year”) to the displayed information.

- The default rating for a player not found in FIDE lists should be 1399.

- When expanding a team, allow adding a player not present in FIDE lists by Surname, and optionally First Name and Elo. Also allow adding a player from the unpaired list. There should therefore be five options: from the user's players (as now), from FIDE (as now), from FIDE ID (as now), from the unpaired list, and with just Surname, First Name, and Elo. “Add player” from list or unpaired should allow a search filter. Consider whether a player added on the fly by Surname should end up in the user's player list—I'd say yes.

- When you do “New team from selected”, focus should immediately go to the name field so you can start typing right away. This is a golden rule that should be applied everywhere; don’t force the operator to click with the mouse to begin writing.

- Sometimes FIDE doesn’t separate Surname from First Name with a comma, so if you add a player from FIDE with these characteristics, even though it’s found it won’t let you proceed because the First Name is missing. That obviously isn’t good. It can be solved by “guessing” which part is the First Name and which is the Surname, but that may not be simple. In my opinion the best solution (as highlighted in the first point) is to accept registration with only the Surname.

- A brief note on importing a file for registrations. We talked about it, but I think we should allow Bulk registration at least for unpaired players. So adding unpaired players should be able to accept a list of players from a text file or even just a box where you paste the list. The format is up to decide, but I think a simple “Surname,FirstName,Elo” one per line would suffice. Alternatively, the line could also allow a FIDE ID (I don’t think there are surnames that are only numbers). At the end of Bulk registration it should produce a report on the number of lines pasted and how many players were actually registered, highlighting any lines that couldn’t be processed for any reason (e.g., nonexistent FIDE ID or parsing failure). It would remain to consider whether a Surname present in FIDE lists could be captured by the list itself, but that risks becoming complicated (homonyms, sometimes with identical Surname and First Name, plus other tricky situations). Better keep it simple: add only the Surname. If no First Name is provided accept without it, and if no Elo set it to 1399. So lines like “Paperino,,1756”, “Paperino,Paolino” or just “Paperino” are all valid.


Hey, can we consider the issue of double Bye and the inability to generate a round after a team withdraws as fully understood and solved for the future? I assure you it was a really unpleasant situation… when there are prizes in addition to the tournament people aren’t very understanding! :)


Thanks and goodbye, as always,

Claudio.

View original (IT)

hello @Claudio

thanks as always for the detailed feedback and for the time you dedicate to getting ChessPairings running in the field. Your reports after a real tournament are worth more than a thousand tests.

I’ll go point by point, starting with your final question which is the most important.

ON THE BUGS OF YOUR TOURNAMENT (double bye and block after team withdrawal)

I’ll be honest: I think so, but I don’t have a 100% guarantee.

Here’s what happened behind the scenes:

1) Double bye: fixed in v4.7.2. The cause was in the TRF we sent to the pairing engine bbpPairings — we declared the bye as “draw with virtual” instead of “bye assigned by the system”, and so the engine had no way of knowing that the team had already taken one. Now we use the correct marker (PAB) and bbp6 automatically honors the FIDE rule “no double bye”.

2) Turn generation blocked after team withdrawal: fixed in v4.7.6. When a team withdrew mid‑tournament, the generated TRF contained references to that team (because other teams had met it) but not its header row, so bbp6 failed with “Invalid line”. Now withdrawn teams are included in the TRF with the flag XXZ which excludes them from pairing but preserves historical consistency.

3) Stress simulator (v4.7.7): we added an automatic test that runs 12 full scenarios (including team withdrawal and double bye) before every new release. If either bug reappears, we notice it before deployment instead of during your tournament.

The calm confirmation will only come after a few of your real tournaments pass through these situations unscathed.

As accurate as the tests are, reality is always more creative.

I’m very sorry about the bad experience; I understand that with prizes on the line there’s no tolerance margin.


═══════════════════════════════════════════════════════════

ON YOUR 7 REQUESTS — available in v4.8.0 (release today)

═══════════════════════════════════════════════════════════


Implemented 3 out of 7 requests. Here’s the detail:


═══ ACCEPTED ═══


✓ B‑Year in “Add unpaired player” results. Now the FIDE search also shows the birth year, both in the unpaired panel and in the team search. It helps a lot with homonyms.

✓ “Add player” in the team expansion — 5 modes. I completely redone that section. Now you find a horizontal pill selector with five options:

1) From my roster (with live filter)

2) Search FIDE (with B‑Year in results)

3) FIDE ID (bulk textarea, as before)

4) Unpaired — selection from the list of unpaired players in this tournament, with filter

5) Manual — Last name + First name + optional Elo, with “add to my roster” checkbox checked by default

Every mode change automatically focuses on the first field (your golden rule). No more mandatory click to start typing.

The player added in “Manual” mode ends up in your roster (if the checkbox is active). If a player with the same last name + first name already exists, that existing one is reused instead of creating a duplicate.

✓ Bulk import of unpaired players

In the unpaired panel there’s a new button “Import list”. It opens a textarea where you can paste one player per line in the format:

LastName,FirstName[,Elo|FIDE_ID]


Valid examples:

Rossi,Mario,1750 → Elo 1750
Verdi,Giovanni,12345678 → lookup FIDE (ID 8 digits or more)
Bianchi,M → Elo 0, name only initial
Neri,Anna → Elo 0


The rule: the third field, if numeric between 0 and 3500, is read as Elo; if >3500 it’s treated as FIDE ID (and in that case last name/first name/rating are taken from the FIDE archive, ignoring what was typed).

At the end a report appears: lines read, players registered, lines discarded with reason for each.

I chose to keep it only as paste, no file upload, for security reasons.


═══ NOT ACCEPTED ═══


✗ Unpaired registration with only Last name (no First name)

I prefer to require at least the initial of the first name. Last‑name‑only risks leaving data too sparse and ambiguous (especially with homonyms). Validation accepts “Rossi M.” or “Rossi Mario”, but not just “Rossi”.

For the same reason, I’m not implementing a fix for FIDE players without a comma between last name and first name — they’re sporadic cases and trying to “guess” the separation would introduce more errors than fixes.

In those cases I recommend adding the player manually with Last name + initial.

✗ Default Elo 1399 for players without rating

The value 1399 is specific to the Italian Federation, while ChessPairings is multilingual and used outside Italy. The default is 0. If 1399 matters for your tournaments, you can obviously type it manually (even in bulk).

✗ Upload file for unpaired import

Only paste in textarea, for app security reasons.


Let me know how the new features work — especially if you find any awkward workflow or something that needs polishing.

Ah, and on the forum: I’ll note the issue of the last page returning to home after login. I’ll look into it separately.

Have good tournaments!

Stefano


Edited on 05/05/2026 08:16

Hello, I had written you the usual tedious review, complete with statistics on the FIDE tables, but when I pressed "Post Reply" it told me that I needed to log in and everything was lost! For some reason sometimes the Forum loses access and requires logging in again. I'm disheartened for having lost everything (I had written a lot) and for not following my rule of always copying the post content before trying to publish it :( Patience, when I regain confidence in the world I'll try again.


Hi,

Claudio.

Hello @Claudio

In the past few days there are five other team tournaments and I have not received any notifications (but five is a small number, and it doesn't mean that none were reported).

Hello @stefanoloberti,

We’re back again, and this time we’ll have three team tournaments (this time with teams of three players) that will be part of a combined event. At the moment I don’t see a way to manage even the combined events, with overall rankings for the various results in each tournament; perhaps we’ll talk about that later. For now we’ll treat them as three separate tournaments; but notice that it would already be useful to duplicate a tournament, or at least export the registrants, who—except for exceptions—will be the same for all three tournaments… otherwise we’ll have to manually create each individual tournament and re-register all the players from the first one. That will also be something we’ll address later.


As usual, I need to bring you a few preliminary observations and some requests for clarification—thanks as always.


  • In the tournament settings, once registrations are open, you can neither view nor modify the tie‑break rules. If I remember correctly, you had this option at the end of the tournament, but it should be possible to do so at any time, especially before the tournament starts.
  • Bug: in the “Player List” (the players from your club, for instance), if you select them all and then try to delete them, it correctly says that it would like to delete them (indicating the total number), but then only deletes one!
  • How can we upload the tournament announcement so that someone can consult it before registering?
  • Maybe I’m not seeing it, but how does a non‑administrator see the list of registrants? There should be a public link pointing to the tournament where you can view its details, see the registrants, download/view the announcement, and use a link to register. Am I missing something, or was this not planned?


Bye,

Claudio.

Hello @LTB today I will be traveling to Basel for the Bundesturnier.


On the train I’ll take a look in detail at the requests even though I think that before introducing new features we should run a stress test to see if what’s in production produces errors and exceptions, so as not to leave the organizer with the hot potato of something broken.


Small note on the announcement: this is not uploadable (like any other file) but there is a notes field where you can write information inside, and what comes out is a page like this: https://my.chesspairings.org/pubblico/torneo.php?id=1381&token=10705c963d87ab2fac5f0dd8e104769b35dc66197c083d3606ec16cfe6561c56&tab=bando

Edited on 13/05/2026 07:32

Hello Stefano,

The point is exactly this: how does the public view this information during the registration phase? If you go to the public link for open registrations, you only see the Standings button, a terse "Standings not available yet", and nothing else (e.g. https://my.chesspairings.org/pubblico/torneo_squadre.php?id=208&token=5f5b5aa47b850102f0424a8bad91d113bad9d40eff9fc4c3fb31bd8177241113)... the "Regulation/Bando" tab is missing. The solution seems "simple": you need to enable the "Participants" and "Regulations" tabs even during registration, otherwise, I repeat, how do players see this information? It's such a big issue that I really suspect I've missed something :)


Good luck for Basel!


Bye,

Claudio.

Hello @LTB, indeed in the team tournament section this is not implemented yet. I will work on it now.

Hello @LTB


I’ll go point by point, starting with the best news: all four of the issues you raised were confirmed in the code and have been fixed in v4.8.9 (online from today).


═══════════════════════════════════════════════════════════

Your 4 Issues — resolved in v4.8.9

═══════════════════════════════════════════════════════════


✓ Standings not visible/modifiable during registrations


Confirmed: the “Configure Standings” card was buried inside the Ranking tab, which is hidden while the tournament is in registration phase (there’s no ranking to show yet). Result: there was literally no way to get there.


I moved it to the Settings tab at the bottom. Now it’s always accessible and editable in any state of the tournament — registrations, ongoing, finished. Same drag‑and‑drop as before, same presets.


✓ Bug “delete all players from the club” that actually deleted only one


Real bug, and pretty ridiculous once you understood it: the page had two nested HTML forms (one for bulk deletion, one inside each row of the table for single deletion). Browsers automatically close the outer form as soon as they encounter the inner one — so only the first checkbox actually made it into the POST. The message “do you want to delete N” was correct because it counted on the client side, but then the server received 1. Fixed.


✓ Uploading the tournament announcement


Technically the field already existed (the “Notes” textarea in settings), but with that generic name no one could guess it was the public announcement. I renamed the field to “Tournament Announcement / Notes”, added an explanatory placeholder (date, venue, prizes, rules, contacts…) and a line below that clarifies: “It will be shown as the Announcement tab on the tournament’s public page.”


✓ Public view during registrations — the biggest one


You were right overall: the public page of a team tournament before registrations only showed the Ranking tab with “Standings not available yet” and nothing else. No registered teams, no announcement, no link to register. You hadn’t missed anything — that was exactly how it worked.


Now the public page of a team tournament has:


- “Teams” tab (always visible, with counter) → list of registered teams, each expandable to see the roster player‑by‑player (title, surname+name, rating, FIDE ID, any reserves at the bottom). During registrations this is the default tab that opens.


- “Announcement” tab → visible when you’ve filled in the tournament notes.


- Prominent green CTA “Register your team” in the header, when online registrations are open. With counter “N / max teams registered” if you set a ceiling.


- “Ranking” / “Pairings” tabs → appear when the tournament starts (round > 0).


- Clear status badge in the header: green “Registrations”, animated LIVE when the tournament is running, gray “Finished” at the end.



═══════════════════════════════════════════════════════════

TEMPLATE DUPLICATION FOR TEAM TOURNAMENTS═══════════════════════════════════════════════════════════


You said “we’ll handle this later too”, but since duplication already existed for single‑player tournaments, replicating the same pattern for team tournaments was a morning’s work. So it’s in.


How it works:


In your list of team tournaments there is a new icon (overlaid sheet, blue) on the right of each tournament. Click → modal with the name pre‑filled as “X (copy)” → confirm → you’re taken directly to the new tournament.


What it copies:

• Full settings (type, rounds, boards, cadence, initial colour, engine, etc.)

• Standings configuration (so you don’t have to redo them each time)

• All active teams (name, abbreviation, captain, captain email, seeding team number, average rating)

• Full roster of players for each team, with board order and starter/reserve flags


What it does NOT copy (intentionally):

• Results, pairings, round line‑ups — the new tournament starts fresh

• Withdrawn teams

• Individual registrants still waiting for assignment

• Public tokens and short code → they’re regenerated anew, so the copy’s links differ from the original’s


The new tournament starts in “registrations” state, round 0, today’s date. From there you modify it normally (final name, dates, any small differences in rosters).


For your set of three tournaments: create the first as usual, duplicate twice, and in 30 seconds you’ll have all three ready with the same players. Estimated savings: about half an hour per tournament that you would otherwise have to re‑register manually.



As always, when you try the new features let me know how it goes — even just “ok works” is valuable, because it confirms the fix holds in production and not just in my tests. I’ve tried to manage this flow (not other team‑tournament flows) and found no errors.


Have a good tournament (to the tournaments, actually!),


Stefano


Great, everything seems addressed, thank you! I'm puzzled by the decision not to copy unpaired players when duplicating a tournament, but that could also work... I would have duplicated them as well; it might be convenient for duplicating a tournament (taking a snapshot) before composing the teams.

Finally, it would be handy if any link in the Notes/Regulations/Band section were clickable, so that if a user inserts a link to their own band or anything else they can reach it by clicking on it. Currently it's all plain text.


Hello,

Claudio.

Hello @LTB, plain text (so no HTML) is safer to avoid malicious link injection that could trigger alerts on the domain.


There are almost a thousand users and every day 1,000 pairings are generated; security is very important.

@LTB I fixed the forum logout bug

Great! But the road to success is paved with difficulties and cranky users! Here’s another batch of considerations gathered during tests to avoid having to do rounds by hand in upcoming tournaments :) Among the considerations, some are aesthetic and others debatable, the most important one concerns being able to modify the tournament settings at any time:


Registrations:

- The public tournament page should allow expanding or collapsing all teams, just like you did on the admin page.


Rounds:

- The round view is “ugly”; it would be better to align the fields. The “Expanded View” works fine, but the “Compact View” has all results misaligned. Even the “Print Round” should have the “RESULT” column centered relative to the page. The public Pairings page is also all misaligned.

- In my opinion, when you click “Start Tournament” it should automatically generate the first round; I find the “Generate Round” button redundant. If the objection is that this allows a Manual Round, that option is still available once the round has been generated, so there’s no need to ask the user to generate the round.

- The lineup management needs refinement… it works well during registration (just drag players with the mouse), but during the tournament it’s unclear. Let’s take a practical case: I make a mistake and start the tournament with an incorrect lineup. I run the first round, and when entering results I realize that a lineup is wrong, but fortunately there’s a “Manage Lineup” button :) Then I change it (and here the change is much less effective; it forces me to temporarily place an empty board and play a three‑card game to correct the final lineup). I click “Confirm Lineup” and everything is fine. I enter my results (here too, the meaning of “Save Results” isn’t clear—it seems redundant as a button...). I generate the next round, and it reverts to the initial lineup. That could be acceptable, but how can I permanently change a lineup until the end of the tournament? So I go to “Lineups”, and there I can change the lineup (with yet another system that even lets you set the same player twice, only to prevent the “Save Lineup” from succeeding; we need to standardize the lineup‑change method). I return to “Pairings”, but the modification isn’t present, so I’d have to change it again there (because if I delete and recreate the round, the change made in “Lineups” is lost. Even worse: after returning to the first round, I change the lineup for round 1, generate round 2, and it reverts to the initial lineup, which no longer exists anywhere! In short, I think we should be able to temporarily change a lineup when entering results (standardizing the change method), and this is fine, but it should also allow me to modify a lineup permanently for subsequent rounds. I remember that during the last tournament exactly this happened: a team was entered with an incorrect lineup, and every round required manually remembering to adjust the lineup before entering results.

- We had already seen this in individual tournaments, but in team ones I can’t find the ability to modify the tournament while rounds are running (e.g., number of rounds or tie‑break methods). This is particularly serious because if you start a tournament with too many rounds for the players, you can’t get out of it: even if you let it happen, you eventually hit a point where you’re stuck with the message “Pairing engine error: Error while pairing /tmp/....trf. No valid pairings exists... etc.” The Pairing Engine error during a tournament *should not* occur; it must be prevented! And in this case there’s no way to escape! Tournament settings should always be accessible from start to finish.


End of tournament:

- The final standings include both team and board rankings, but the Export (PDF, CSV, etc.) includes only the team ranking and not the board ranking. Either add it after the team ranking or provide a specific button to export it. Also the board ranking doesn’t use any Tie Breaks; those should be provided there as well.


Hi,

Claudio.

hello @LTB

the usual solid feedback battery, always with the advantage of coming from the tournament hall and not from a lab test — thanks.

v5.4.0 is online today and contains five of the six points you raised. The sixth (the launch that also generates round 1) I left out by choice.


I’ll go point by point following the structure of the reply.

═══════════════════════════════════════════════════════════

REGISTRATIONS — expand/collapse public page

═══════════════════════════════════════════════════════════

✓ Done.

On the tournament’s public page, above the list of teams, there are now two buttons “Expand all” / “Collapse all”, identical to those in the admin. The individual triangles on each team’s

continue to work independently, so you can open only the teams that interest you or open them all at once, as you prefer.

═══════════════════════════════════════════════════════════

ROUNDS — alignment

═══════════════════════════════════════════════════════════

✓ Done on all three fronts you mentioned.

  1. Compact view of pairings (admin) — the problem was that the header card row behaved like a free “flex” space: if one team name was longer than another, the score to the right would shift by a few pixels. I converted it to a grid with a fixed score column and tabular numbers (so “1.5 – 0.5” and “2 – 0” occupy the same width). Now the results are aligned even when scrolling vertically.
  2. Round print — the RESULT column was 55 px wide, too narrow for “½‑½”. I increased it to 78 px, set table-layout: fixed, vertical-align: middle. The row now breathes and is symmetrical with the page.
  3. Public pairings page — the grid was rigid and long names broke alignment. Rewritten with named columns and minmax(0, 1fr) on names, tabular-nums on rating and result.


While working on it I also caught a bug you hadn’t reported but that manifested itself: in the TXT export of the team standings, the line “LTBagna Càuda” was misaligned by one character compared to the others. Cause: the “à” is 2 bytes UTF‑8 and PHP counted bytes instead of characters when padding the column. Replaced sprintf with mb_str_pad. The line is now straight.

═══════════════════════════════════════════════════════════

ROUNDS — managing rosters

═══════════════════════════════════════════════════════════

✓ Done the important thing. I didn’t unify the three UIs under a single component (that would have been too invasive for now), but I solved the functional problem you described.

The case you told me about — “a team starts with the wrong roster, every round I have to remember to fix it manually” — is now handled like this:

  1. In each of the three places where you can currently edit a roster (drag‑and‑drop in registration, Roster tab, “Manage Roster” during a round) there’s a checkbox below the roster: “☐ Also apply as default roster for future rounds”. If left unchecked, the change applies only to this round (current behavior, useful for cases like “today I keep X on the bench because they had a fever”). If you tick it, the change becomes the NEW default roster: the lineup is reordered (default_board updated) and all future rounds start from there instead of the initial order.
  2. Server‑side anti‑duplicate validation everywhere. Previously the “Rosters” tab let you put the same player on two boards (drag‑drop in registration, etc.) and then failed at save with a vague error. Now in all three flows (setRoster, updateDefaultRoster, regenerateMatchesInRound) it’s rejected with an explicit message: “The same player is assigned to two boards (1 and 2). Correct the roster before saving.”


Essentially: during the tournament, if at round 2 you notice a team’s roster was wrong, tick the checkbox once and from rounds 3‑4‑5 that correct one is used. No more “remember each round”. I might unify the graphics later, but the value is already taken by the current version.

On the “Save results” button that seemed redundant to you: the label isn’t optimal, I left it because the button makes the definitive commit of results that until then are autosaved (history updates only on click). But you’re right that it’s not very clear. I’ll think about it.

═══════════════════════════════════════════════════════════

ROUNDS — changing settings in progress + “Pairing engine error”

═══════════════════════════════════════════════════════════

✓ Done, and I think it’s the most important fix of this round.

The case you described — tournament with 9 rounds and 6 teams, you get “No valid pairings exists” and can’t escape it — now is no longer possible. Two things:

  1. The “Settings” tab of the team tournament was visible only during registration. I made it always visible, in any state (registrations, ongoing, finished). When the tournament starts you see a yellow banner “⚠ Tournament in progress…” that clarifies what you can change (number of rounds, byes) and what you can’t (tournament type, number of boards — changing those after start would cause damage). The “Number of rounds” field has min=current_round, so you can never reduce it below the round you’re playing.
  2. Before calling pairing engine I added a sanity‑check: etc.

    ciao @LTB

    solid standard battery of feedback, always with the advantage of coming from the tournament hall and not from a lab test — thanks.

Hello Stefano,

Wow! So many things addressed in such a short time... congratulations!

There are still some graphic glitches, but we’ll fix those once the important stuff is sorted out! :)


A small apparent oversight: I still get the Pair Engine Error if I change the number of rounds for an ongoing tournament… it accepts an exaggerated number, and then when it can no longer generate a round the error message appears. But it lets me create a manual round without any warning (and that’s fine; let it be, as long as it doesn’t cause more headaches).


In my opinion you should also allow reopening a finished tournament; right now it seems there is no way to do that. Here’s a practical scenario: I add the last round, finish the tournament and publish the standings; then someone pops up claiming their result from the last round is wrong! What do I do?


I also realized I can withdraw a team, but I’m not able to add a team to an already started tournament. If a latecomer wants to join from the second round, what should I do?


Everything else is great! Now, to manage our combined event, I’ve built a small web app where I can feed it exported “TXT (Report)” standings (which are as good as gold), analyze them and produce a combined ranking for the various tournaments, weighting results by the number of rounds in each tournament. If you’re interested, I’ve parked it on my own web space; I can send you the URL privately. Currently it only calculates team rankings, but now that you added board standings to the export I’ll also include those (hope you won’t change the layout soon…). Maybe one day you’ll even implement the combined event concept.


Thanks again and goodbye.

Claudio.

Hello @LTB


Thank you for the reply and for returning to the open points with your usual precision. I’ll address the three topics you raised, plus a footnote on the combined event.


═══════════════════════════════════════════════════════════

PAIRING ENGINE ERROR — truly closed this time (hopefully)

═══════════════════════════════════════════════════════════


✓ Done. You were right: even after the v5.4.0 fix you still got it. I performed an autopsy and found two bugs that had slipped in:


(1) The settings save accepted any `num_turni` in the 1‑30 range without checking the theoretical maximum Swiss for active teams. So if you set “20 rounds” with 6 teams, the save went through and you hit a dead‑end when the engine reached the limit.


(2) The fallback that caught the technical error to rephrase it user‑friendly only matched the string “no valid pairings”. If bbp6 returned “Pairing engine error” verbatim (or “Cannot pair”, or other internal phrasing), the cryptic message passed through unchanged.


The interesting part of your observation is the phrase “but let me generate a manual round without warning, and that’s fine, let’s leave it”. I took that as an explicit spec: the point is NOT to prevent you from saving high `num_turni` — that would cut off the manual pairing escape valve. The point is to avoid leaving you stuck in front of a cryptic error.


So I structured the fix in three layers:


• Settings save: if you set `num_turni > max_theoretical` during an ongoing tournament, the save passes but shows a yellow warning: “Attention: with 6 active teams automatic pairing covers at most 5 rounds. Excess rounds will need to be generated manually.” You see it and know what to expect.


• Automatic pairing (Generate round): blocks with a message that explains the exit path — “Automatic pairing exhausted for 6 active teams (theoretical maximum 5 rounds). Use ‘Manual pairing’ to generate additional rounds, or reduce num_turni to 5 and conclude the tournament.” No more dead‑ends without operational instructions.


• Manual pairing: never blocked. Exactly as you asked.


Additionally, regardless of the three layers above, I broadened the engine error catch so it also intercepts “Pairing engine error” verbatim and any other generic technical phrasing. If for any reason bbp6 fails for other causes (e.g., unsatisfiable color constraints at round 3 with a theoretical max of 5), instead of propagating the raw string you see: “The pairing engine failed to generate the round (...). Possible causes: too many rounds for active teams, unsatisfiable color constraints. You can use ‘Manual pairing’ or reduce num_turni and conclude.”


In short: “Pairing engine error” and friends should never again reach the arbiter in the room. Never again, truly this time.


═══════════════════════════════════════════════════════════

REOPEN CONCLUDED TOURNAMENT — done

═══════════════════════════════════════════════════════════


✓ Done. Your practical case is a perfect spec: the arbiter concludes the tournament, publishes the standings, and an incorrect result from the last round disappears. Now there’s a legitimate path.


In a concluded team tournament, beside the final step you’ll find a yellow “Reopen Tournament” button with explicit confirmation. Clicking it:


• The tournament status returns to “in progress”

• The final team standings are reset (they will be recalculated on the next “Conclude”)

• The current round remains unchanged (we’re at the last one), so the results UI becomes immediately available for correction

• Correct the wrong result and press “Conclude Tournament” again — the final standings are recalculated and reassigned


Curiosity: this function already existed for individual tournaments since v4.8.5 (no one had ever asked me about it for teams before you). Symmetry is good now.


═══════════════════════════════════════════════════════════

ADD TEAM TO STARTED TOURNAMENT — postponed to v5.6, and here’s why

═══════════════════════════════════════════════════════════


I’m not closing this one, and I want to be honest about the reason.


The UI is trivial (unlock the “Add Team” form even when the status is “in_progress”). What’s NOT trivial is telling bbp6 that there is a team that hasn’t played past rounds. The TRF FIDE format has no official code for “team entered at round N”. One could:


• leave nothing for missed rounds (line 001 shorter than the others)

• write “Z” (zero‑point bye) for each missed round — but Z means “permanent withdrawal”, bbp6 might exclude it even from the current round

• write “U” (unplayed) — not officially FIDE but supported by some engine versions

• write “H” (half‑point bye) — would give free points, wrong


Which of these does bbp6 accept so that it produces valid pairings (with the new team actually included in the current round)? I can’t test it cold: I can only try in production and from Basel it’s hard for me.


To avoid writing blind productive code on a case that during a live tournament would be particularly annoying to discover broken, I prepared a targeted PoC and already ran it. It builds an in‑memory Swiss 4+1 team tournament (no DB touch), tries the four strategies above, calls real bbp6 for each, and shows pairings/error.


Net result: SHORT and Z both work and bbp6 includes the new team in the current round pairings (Echo plays against Alpha in round 3, perfect). U and H fail because bbp6 checks that the points sum of the rounds in line 001 matches the declared points field, and it doesn’t recognize those codes.


Implementation side, the PoC discovery simplifies my work: in v5.6 I unlock the “Add Team” form even for a tournament in progress (with a warning like “team without points for past rounds”), assign the next team number after the last (without reordering others, otherwise historic pairings break) and that’s it. The fallback Z in the TRF generator already exists, so I don’t even need to write fake records to DB. Estimate 1‑2 hours + test. I'll give you it in v5.6 without rush — let me know if in future tournaments someone gets late and you notice you need it immediately.Hello @LTB


thank you for the reply and for coming back to the open points with the usual precision. I’ll address the three topics you raised, plus a footnote on the combined.


═══════════════════════════════════════════════════════════

PAIRING ENGINE ERROR — really closed this time, hopefully

═══════════════════════════════════════════════════════════


✓ Done. You were right: despite the v5.4.0 fix you still got it. I did an autopsy and found two gaps that had slipped in:


(1) The settings save accepted any num_turni in the 1-30 range without checking the theoretical maximum Swiss for active teams. So if you set “20 rounds” with 6 teams it saved smoothly and you hit a dead‑end when the engine reached the limit.


(2) The fallback that catches the technical error to rephrase it user‑friendly only matched the string “no valid pairings”. If bbp6 returned “Pairing engine error” verbatim (or “Cannot pair”, or other internal formulations), the cryptic message stayed intact.


The interesting part of your observation is the phrase “but it lets me generate a manual round without blipping, and that’s fine, let’s leave it”. I took it as an explicit spec: the point isn’t to stop you from saving high num_turns — that would cut off the manual pairing relief valve. The point is to avoid ending up before a cryptic error.

Edited on 17/05/2026 10:43

Hello Stefano,

I tried the changes. The ability to reopen the tournament works, and I assure you that it is an indispensable save point!

- Pair Engine Error: I confirm that messages now seem to be captured and repackaged… maybe one could say that the time it takes for the long and complicated message to appear hardly allows you to read it; a message like this (which probably causes panic) should ask for confirmation before continuing. However, there is a blocking oddity: with a tournament of 6 teams each consisting of three players, even though the program accepts a number of rounds greater than 5, it seems impossible to go beyond the third round (instead of the fifth as logic would suggest). Can you check if it’s really bbp6 being picky, or is there some other reason? If I delete all the rounds (a somewhat long operation if the number of rounds is high), and change the tournament from Swiss to Round Robin (even though it accepts an incongruent number of rounds… in the case of round robin you should “gray out” the number of rounds to n‑1. Also because silently the program changes the number of rounds to n‑1 as soon as you start the tournament, even if you had set a different number), the tournament finishes normally with 5 rounds. Sorry for the excessive use of parentheses to describe the situations, but I’m writing while testing.

- Late registration: I understand the implications. The Place Holder trick is definitely not simple, and you should always plan it in advance :) Let’s see if the PoC can validate the introduction of a new team at any time…


Suggestion: in the “Round Print”, which the referee usually uses to print and post the rounds, add a QR Code in the top right that points to the public tournament page, so anyone who wants can frame it and see the rounds on their phone, including upcoming ones…


Bye,

Claudio.

hello @LTB

first of all the important thing: I identified and fixed the block on your 6-team Swiss. It goes into v5.5.1, I'll explain below. I'll answer the other points in order.


═══════════════════════════════════════════════════════════

BLOCKING BUG — 6 TEAMS STOP AT ROUND 3 (FIX v5.5.1)

═══════════════════════════════════════════════════════════

✓ Done. And you were right about the suspicion that "bbp6 is being picky": the culprit was indeed bbp6, but because of incorrect information we were passing to it.

Root cause: in the TRF we send to the engine there’s a record (XXR) that declares how many rounds the tournament will last. If you set num_turns=7 with 6 teams, we wrote “XXR 7” exactly. bbp6 then does a lookahead: it sees that the theoretical maximum of a Swiss with 6 teams is N‑1 = 5 distinct rounds, calculates that after round 3 only 2 rounds remain to pair against the 4 declared, and rejects the pairings from round 4 onward with “no valid pairings”. It’s not being picky; it’s FIDE‑compliant: the engine doesn’t want to start a tournament it knows it can’t finish.

Solution: in the TRF we cap XXR at max_theoretical (5 in your case) BEFORE sending it to bbp6. The num_turns you set for the tournament stays unchanged in the database — so any extra rounds can still be generated manually, exactly as v5.5.0 intended. Simply, bbp6 only sees what it can finish automatically.

Practical consequence for you: your 6‑team Swiss now pairs smoothly up to round 5 regardless of the num_turns you set (5, 6, 10, 30 — it doesn’t matter). Rounds 6+ you can still generate manually if needed.

Automatic tests written to harden this: 4 scenarios (even cap, odd cap with a team withdrawn, no‑cap when num_turns is already in range), all pass.

═══════════════════════════════════════════════════════════

ROUND ROBIN — silent num_turns (deferred, non‑blocking)

═══════════════════════════════════════════════════════════

You’re right: in Round Robin the num_turns value is actually unused (Berger’s algorithm always sets N‑1 for even N, N for odd N). But today the field is a free input, and that can be confusing.

I’ll put it on the list for the next patch (v5.5.2 or v5.6): when type_tournament='round_robin' the num_turns field becomes disabled/grayed out and auto‑updates to N‑1 (or N with BYE) as soon as you change the number of teams, with a small tooltip explaining why.

I didn’t include it in v5.5.1 because it’s cosmetic UX and the fix above was urgent: better not slow it down.

═══════════════════════════════════════════════════════════

ENGINE ERROR — the message disappears too quickly

═══════════════════════════════════════════════════════════

Fair point. Today it’s a yellow/red flash that auto‑dismisses, but if the arbiter is in the room and about ten players are asking “when do we start?”, they don’t see it.

In v5.5.2 (or v5.6) I’ll turn it into a modal with an explicit “Got it” confirmation for pairing engine errors. The other informational flashes stay as they are — I don’t want to clutter the UX on routine stuff, but for a pairing engine error it must be persistent.

═══════════════════════════════════════════════════════════

QR CODE IN ROUND PRINTING — already there!

═══════════════════════════════════════════════════════════

Good news: the QR code in “Print round” has been in production for a while, both for individual and team tournaments. You’ll find it at the top right of the A4 printout. It points directly to the tournament’s public page where players see pairings and standings in real time.

The reason you might not have seen it: it only appears if the tournament has public visibility enabled (and thus a generated public_token). If you leave the tournament settings as “private”, the QR is not printed (it would be useless, the page wouldn’t be accessible).

So:

  1. Go to Tournament Settings
  2. Visibility → “Public”
  3. Save
  4. Re‑print the round → the QR code will appear at the top right


If instead you meant a QR on the registration sheet or on the standings, let me know and I’ll add it there.

═══════════════════════════════════════════════════════════

LATE REGISTRATION — PoC in progress

═══════════════════════════════════════════════════════════

I confirm that the PoC I mentioned in v5.5.0 is giving positive signals (Z and SHORT both work with bbp6). I’ll ship it in v5.6 when I’ve integrated it cleanly into the “Add team to ongoing tournament” form. You’re right about the placeholder being a crutch — the reality is that until v5.6 it’s the only sure way, and I apologize for that.

═══════════════════════════════════════════════════════════


In short:

• v5.5.1 (today): fix 6‑team bug, i.e., the blocking point

• v5.5.2/v5.6 (soon): RR greyout, modal confirmation for engine error

• v5.6: validated PoC for late registration


When you have a moment, try your 6‑team Swiss with the num_turns you want: it should run through round 5 without “Pairing engine error” or stopping at round 3. Let me know how it goes.


Hello Stefano,

I’m glad we found this “bug” in the bbp6 feed; it was pretty nasty! And I saw that you’ve already installed version 5.6.3. I tried it, but Generate Round fails with the same message (this time modal). I also tried deleting the round (the third one) and recreating it, but it always stops at the third round and never generates the fourth. So I deleted all rounds to restart from Start Tournament, and it worked up to the fifth. At this point I suspect that the change only takes effect if the tournament was started with the new version; otherwise the XXR had already been sent.

Yes, the number of rounds for Round Robin isn’t urgent, it can wait.

But I don’t see the QR Code at all :) Obviously I’m referring to the “Print round” in the admin panel, because that’s what the arbiter prints and posts in the room. For example, this link: https://my.chesspairings.org/stampa_abbinamenti_squadre.php?id=225&turno=1. Whereas in the public section there is indeed a QR Code pointing to Telegram (“Follow this tournament on Telegram”), but the dedicated box is still all white (e.g. https://my.chesspairings.org/pubblico/torneo_squadre.php?id=225&token=1cc53800c380a43d37ab097d5509b97ace5f78718b7e09f3a725f8ddcd0fdeb8). But if I’m already on the public page, I don’t need a QR Code to the public page; it’s for those who see the round printed by the admin. And when I go into the tournament settings, I can’t find a “Visibility → Public” flag; I only see an “Online team registrations” and “Online individual registrations”. Same thing in the tournament creation. Also, as you mentioned, there should be a QR Code also on the leaderboard (pointing to the public leaderboard), plus for convenience to give more visibility to your program. So I’m a bit confused here. But I found the flag in individual tournaments; maybe you didn’t propagate it to teams?!

I’m also confused about the possibility of adding latecomers… I understood that from 5.6 there would be this option, I see 5.6.3 online, but I don’t see an “Add team to ongoing tournament”… maybe I misunderstood.


Bye,

Claudio.


Edited on 18/05/2026 21:38

hello @LTB

I closed all three points you had reported after v5.6.3. I’ll recap them in order. They’re all already in production (v5.6.9 to the footer).

═══════════════════════════════════════════════════════════

LATE REGISTRATION FOR TEAM LAGGARDS — v5.6.4

═══════════════════════════════════════════════════════════


✓ Done. Replicated the pattern of individual tournaments (already existed in mig 051) also for teams.

How it’s activated: in Tournament Settings you’ll find a new flag “Allow late registration” (visible only for Swiss, the RR by definition has a fixed calendar). When active and the tournament is ongoing, the Teams tab shows an orange card “Add team to ongoing tournament”. The team enters from the next round at 0 points and with number_squadra MAX+1 (I don’t renumber the original seeding, I keep the TRF history of bbp6 consistent).


The PoC (Proof of Concept) I told you about in v5.5.0 confirmed that bbp6 accepts “0000 - Z” for past rounds (zero-point bye, FIDE C.04.2 Art. 2.4) — so this is the format now in production, no fragile placeholders.

On the XXR cap you made me think of an important detail: if you add a team the theoretical max grows (e.g., from 6 teams to 7, max goes from 5 to 7). But if that team then withdraws it returns to 6 teams — and in v5.5.1 the cap was recalculated to max(N-1)=5, lowering the limit again and potentially breaking pairings already produced with a cap of 7. Adopted solution (let’s call it “option 3”): I store the theoretical max AT THE START OF THE RUN in a column `xxr_baseline`. The effective cap in the TRF is now `MAX(xxr_baseline, current_theoretical_max)`. Late entry raises the cap, withdrawals don’t lower it below the baseline.

Test: I added 12 new automatic tests to the teams test runner (PART C + PART D) — 31 green out of 31. The C10 in particular confirms that bbp6 correctly generates a round with 3 to 5 teams when the baseline is still 3 (real engine call, not just logical precheck).

══════════════════════════════════════════════════════════

QR CODE — PUBLIC VISIBILITY AND PRINTING RANKINGS (v5.6.5)

═══════════════════════════════════════════════════════════

On the QR Code point in the public view you hit a hole: the “Private/Public visibility” flag existed on individual tournaments but not on teams — I had left them “always technically public” via autogenerated token_pubblico, a choice that was functional for the Telegram follower system but incoherent as UX. Now teams also have the toggle, with one difference from individuals: default ‘public’ (for new and legacy via backfill) — so I don’t break existing followers. When you set it private the public page gives 404, no QR in prints and Telegram broadcasts suspend themselves.

Print ranking: new page `stampa_classifica_squadre.php` (similar to stampa_abbinamenti_squadre) with a QR at top right that leads to the live public ranking. I made one also for individuals. You find it with the “Print ranking” link next to the Export menu, in the Ranking tab. A4 portrait, auto‑print.

═══════════════════════════════════════════════════════════

WHITE TELEGRAM QR IN THE PUBLIC VIEW (v5.6.6 → v5.6.9)

═══════════════════════════════════════════════════════════

This point was the most gnarly. The QR library we used (davidshimjs/qrcodejs, a 2013 version) stopped working on Chrome 148+: error `f.getPatternPosition is not a function` reproducible on any text, any correctLevel. Identical in incognito and with inline or external lib — nothing to do with cache or extensions. Probably a JIT optimization that can’t digest old minification.

Solution: I replaced it with Kazuhiko Arase’s `qrcode-generator`, the authoritative lib from which qrcodejs forked, current version, scalable inline SVG output. Single helper `renderQR(element, text, sizePx)` on all 10 project pages that generated QR (the 4 prints + the 2 public pages + registration + profile + user dashboard + marathon).

Result: QR now works everywhere, on all browsers. Tests on your Chrome should pass on first try.

═══════════════════════════════════════════════════════════

XXR TOURNAMENTS ALREADY “BROKEN” — BACKFILL + DIAGNOSTIC (v5.6.7)

══════════════════════════════════════════════════════════

On the point you raised about ongoing tournaments that already had inflated historical XXR: I did two things.

  1. (1) Backfill (migration 074): I retroactively wrote `xxr_baseline` on 22 legacy Swiss in_progress/finished with baseline NULL. The calculated value is identical to the cap that would now apply — so no current behavior changes, but legacy tournaments become robust against future withdrawals and protected by option 3 exactly like those created in v5.6.4+.
  2. (2) Tournament health diagnostics: at the top of the Swiss tournament page, if `num_turni > max_teorico_effettivo`, a permanent yellow banner appears stating how many active teams there are, what the maximum reachable Swiss is, and suggests reducing num_turni or using manual pairing for excesses. Previously this warning only appeared after attempting an action (save or generate round); now it’s visible at a glance as soon as you open the tournament. The specific warning in `aggiorna()` and the preventive block in `generaTurno()` still give the right message at the right time.

═══════════════════════════════════════════════════════════

XXR TOURNAMENTS ALREADY “BROKEN” — BACKFILL + DIAGNOSTIC (v5.6.7)

══════════════════════════════════════════════════════════

We translate.

hello @LTB

I closed all three points you had reported after v5.6.3. I’ll recap them in order. They’re already in production (v5.6.9 on the footer).

═══════════════════════════════════════════════════════════

Swiss Late Registration for Teams — v5.6.4

═══════════════════════════════════════════════════════════


✓ Done. Replicated the individual tournaments pattern (already existed in mig 051) also for teams.

How to activate: In tournament settings you’ll find a new flag “Allow late registration” (visible only for Swiss, as RR has a fixed calendar by definition). When active and the tournament is running, an orange card appears on the Teams tab saying “Add team to ongoing tournament”. The team enters at the next round with 0 points and number_squadra MAX+1 (I don’t renumber the original seeding, I keep the TRF bbp6 history consistent).

12»
Log in to join the discussion
This site uses technical and analytics cookies to improve your experience.