From fd099678516d76c3f356cdd4d7ab931d64f4e2d1 Mon Sep 17 00:00:00 2001 From: glass beadian Date: Mon, 12 Oct 2026 22:57:00 +0000 Subject: [PATCH] Provisioner: retry onboarding posts (fresh-room forward-extremities race), degrade non-fatally --- apps/api/src/collectives/matrix-provisioner.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/apps/api/src/collectives/matrix-provisioner.ts b/apps/api/src/collectives/matrix-provisioner.ts index 7b216b4..3947ade 100644 --- a/apps/api/src/collectives/matrix-provisioner.ts +++ b/apps/api/src/collectives/matrix-provisioner.ts @@ -186,7 +186,23 @@ export class MatrixProvisioner implements ProvisionerPort { power_level_content_override: this.powerLevels(input), }); for (const [index, text] of onboardingSequence(input.language).entries()) { - await this.post(roomId, index, { msgtype: "m.text", body: text }); + // A brand-new room can reject the first posts until its initial events + // settle ("no forward extremities"); retry rather than fail the whole + // collective for a race measured in milliseconds. + let lastError: unknown = null; + for (const delayMs of [0, 1000, 2500, 5000]) { + if (delayMs > 0) await new Promise((r) => setTimeout(r, delayMs)); + try { + await this.post(roomId, index, { msgtype: "m.text", body: text }); + lastError = null; + break; + } catch (err) { + lastError = err; + } + } + if (lastError !== null) { + this.logger.warn(`onboarding guide post ${index} failed after retries in ${roomId}: ${errorText(lastError)}`); + } } if (input.founderMxid !== null) await this.inviteUser(roomId, input.founderMxid); return { roomId };