{"record":{"id":"a1cda5c7c64ec251","repo":"Yeachan-Heo/oh-my-codex","slug":"cannot-record-final-review-blockers-for-goal-id-a1cda5","errorCode":null,"errorMessage":"Cannot record final review blockers for ${goal.id}; it is not the only unresolved ultragoal story.","messagePattern":"Cannot record final review blockers for (.+?); it is not the only unresolved ultragoal story\\.","errorType":"exception","errorClass":"UltragoalError","httpStatus":null,"severity":"error","filePath":"src/ultragoal/artifacts.ts","lineNumber":2093,"sourceCode":"      qualityGate,\n      message: 'Aggregate ultragoal plan completed with a clean final quality gate.',\n    });\n  }\n  return plan;\n  });\n}\n\nexport async function recordFinalReviewBlockers(cwd: string, options: RecordFinalReviewBlockersOptions): Promise<{ plan: UltragoalPlan; blockedGoal: UltragoalItem; addedGoal: UltragoalItem }> {\n  return withUltragoalMutationLock(cwd, async () => {\n  const plan = await readUltragoalPlanUnderLock(cwd);\n  const goal = plan.goals.find((candidate) => candidate.id === options.goalId);\n  if (!goal) throw new UltragoalError(`Unknown ultragoal id: ${options.goalId}`);\n  assertNonEmpty(options.evidence, '--evidence');\n  if (goal.status !== 'in_progress') {\n    throw new UltragoalError(`Cannot record final review blockers for ${goal.id} while it is ${goal.status}; start or resume the ultragoal first.`);\n  }\n  if (!isFinalRunCompletionCandidate(plan, goal)) {\n    throw new UltragoalError(`Cannot record final review blockers for ${goal.id}; it is not the only unresolved ultragoal story.`);\n  }\n\n  const now = iso(options.now);\n  const expectedObjective = expectedCodexObjective(plan, goal);\n  const aggregateMode = codexGoalMode(plan) === 'aggregate';\n  const reconciliation = reconcileCodexGoalSnapshot(\n    options.codexGoal === undefined ? null : parseCodexGoalSnapshot(options.codexGoal),\n    {\n      expectedObjective,\n      acceptedObjectives: aggregateMode ? compatibleCodexObjectives(plan) : undefined,\n      allowedStatuses: ['active'],\n      requireSnapshot: true,\n      requireComplete: false,\n    },\n  );\n  if (!reconciliation.ok) {\n    throw new UltragoalError(formatCodexGoalReconciliation(reconciliation));\n  }","sourceCodeStart":2075,"sourceCodeEnd":2111,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/ultragoal/artifacts.ts#L2075-L2111","documentation":"recordFinalReviewBlockers only applies to the final unresolved ultragoal story — isFinalRunCompletionCandidate(plan, goal) returned false, meaning other unresolved goals exist or this goal is not positioned as the final story.","triggerScenarios":"Calling recordFinalReviewBlockers when other goals are still unresolved (not complete/terminal), so the target isn't the sole remaining story.","commonSituations":"Recording blockers mid-plan while sibling goals are still open; trying to block a non-final goal; plan ordering changed after creation.","solutions":["Resolve or complete the other outstanding goals first so the target becomes the only unresolved story","If multiple goals need review blockers, complete the earlier ones before final review","Verify plan ordering and goal statuses before invoking the final-review flow"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!isFinalRunCompletionCandidate(plan, goal)) { throw new Error('other unresolved goals remain — finish them first'); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Complete sibling goals before final review","Treat recordFinalReviewBlockers as a final-story-only operation"],"tags":["ultragoal","review-blockers","final-run","workflow"],"backgroundTag":"workflow-precondition-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}