{"record":{"id":"d782a78965a5c703","repo":"Yeachan-Heo/oh-my-codex","slug":"canonical-scale-up-rollback-membership-verificatio","errorCode":null,"errorMessage":"canonical_scale_up_rollback_membership_verification_failed","messagePattern":"canonical_scale_up_rollback_membership_verification_failed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/team/scaling.ts","lineNumber":955,"sourceCode":"            });\n          }\n          await commitTeamMembershipTaskTransaction(sanitized, leaderCwd, {\n            baseGeneration: currentConfig.config_generation ?? 0,\n            tasks: taskChanges,\n            config: { oldBytes: currentConfigBytes, newBytes: JSON.stringify(desiredConfig, null, 2) },\n            manifest: { oldBytes: currentManifestBytes, newBytes: desiredManifestBytes },\n            recoverToNewOnFailure: true,\n            retainJournalOnSuccess: true,\n            failRollbackPersistence: hasScaleUpFailureInjection(env, 'rollback-membership-persistence'),\n            failRollbackPersistenceAfter: hasScaleUpFailureInjection(env, 'rollback-membership-config-persistence')\n              ? 'config'\n              : hasScaleUpFailureInjection(env, 'rollback-membership-manifest-persistence')\n                ? 'manifest'\n                : undefined,\n          });\n          const verified = JSON.parse(await readFile(configPath, 'utf8')) as TeamConfig;\n          if (!verified || retainedWorkers.some((worker) => !verified.workers.some((entry) => entry.name === worker.name && entry.pane_id === worker.pane_id))) {\n            throw new Error('canonical_scale_up_rollback_membership_verification_failed');\n          }\n          if (verified.workers.some((worker) => rollbackWorkerNames.has(worker.name) && !unresolvedWorkerNames.has(worker.name))) {\n            throw new Error('canonical_scale_up_rollback_resolved_membership_verification_failed');\n          }\n          await finalizeTeamMembershipTaskTransaction(sanitized, leaderCwd);\n          Object.assign(config, verified);\n        });\n      } catch (rollbackError) {\n        const journalPath = join(teamStateRoot, 'team', sanitized, '.membership-task-transaction.json');\n        const suffix = existsSync(journalPath) ? String(rollbackError) : `no_recoverable_journal:${String(rollbackError)}`;\n        return { ok: false, error: `scale_up_rollback_membership_persistence_failed:${suffix}` };\n      }\n      const cleanupWorkerNames = new Set([\n        ...rollbackWorkers\n          .filter((worker) => typeof worker.pane_id !== 'string' || resolvedPaneIds.has(worker.pane_id))\n          .map((worker) => worker.name),\n        ...(context.workerName && !unresolvedWorkerNames.has(context.workerName) ? [context.workerName] : []),\n      ]);","sourceCodeStart":937,"sourceCodeEnd":973,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/team/scaling.ts#L937-L973","documentation":"Thrown during scaleUp rollback verification: after persisting retained workers, the on-disk config does not contain every retained worker with matching pane_id, or contains a rollback worker that should have been removed (see sibling error canonical_scale_up_rollback_resolved_membership_verification_failed).","triggerScenarios":"Scale-up failure path persists the retained membership, then verification via readTeamConfig/readFile finds missing/mismatched retained workers or resurrected rollback workers.","commonSituations":"Failure injection testing (rollback-membership-manifest-persistence), concurrent config writers, or partial writes during rollback.","solutions":["Inspect the team config file on disk for missing/extra worker entries","Restore from the transaction's recorded old bytes or recreate the team state","Re-run scaleUp once membership is consistent; disable failure-injection env vars if testing"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"const cfg: TeamConfig = JSON.parse(await readFile(configPath, 'utf8')); const ok = retained.every(w => cfg.workers.some(e => e.name === w.name && e.pane_id === w.pane_id)) && !cfg.workers.some(w => rollbackNames.has(w.name));","typeGuard":null,"tryCatchPattern":"try { await scaleUp(...) } catch (e) { if (e.message.includes('rollback_membership_verification_failed')) { await restoreTeamConfigFromTransaction(); } else throw e; }","preventionTips":["Keep transactional backups of team config/manifest","Serialize scaling operations with a lock","Turn off scale-up failure injection flags in production"],"tags":["scaling","rollback","membership","verification"],"backgroundTag":"rollback-verification-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}