{"record":{"id":"086a3036e283f3c4","repo":"Yeachan-Heo/oh-my-codex","slug":"missing-label","errorCode":null,"errorMessage":"Missing ${label}.","messagePattern":"Missing (.+?)\\.","errorType":"validation","errorClass":"UltragoalError","httpStatus":null,"severity":"error","filePath":"src/ultragoal/artifacts.ts","lineNumber":1130,"sourceCode":"    total: plan.goals.length,\n    pending: plan.goals.filter((goal) => goal.status === 'pending').length,\n    inProgress: plan.goals.filter((goal) => goal.status === 'in_progress').length,\n    complete: plan.goals.filter((goal) => goal.status === 'complete').length,\n    failed: plan.goals.filter((goal) => goal.status === 'failed').length,\n    reviewBlocked: activeReviewBlocked,\n    historicalReviewBlocked: plan.goals.filter((goal) => goal.status === 'review_blocked').length - activeReviewBlocked,\n    needsUserDecision: plan.goals.filter((goal) => goal.status === 'needs_user_decision').length,\n    superseded: plan.goals.filter((goal) => goal.steeringStatus === 'superseded').length,\n    steeringBlocked: plan.goals.filter((goal) => goal.steeringStatus === 'blocked').length,\n    aggregateComplete: plan.aggregateCompletion?.status === 'complete',\n    artifactComplete: isUltragoalDone(plan),\n    activeGoalId: plan.activeGoalId,\n  };\n}\n\nfunction assertNonEmpty(value: string | undefined, label: string): string {\n  const trimmed = value?.trim();\n  if (!trimmed) throw new UltragoalError(`Missing ${label}.`);\n  return trimmed;\n}\n\nexport function parseUltragoalSteeringDirective(raw: string): UltragoalSteeringProposal | null {\n  const trimmed = raw.trim();\n  if (!trimmed || trimmed.length < 5) return null;\n  try {\n    const parsed = JSON.parse(trimmed) as UltragoalSteeringProposal;\n    if (!parsed || typeof parsed !== 'object') return null;\n    if (!parsed.kind || typeof parsed.kind !== 'string') return null;\n    if (!parsed.source || typeof parsed.source !== 'string') return null;\n    if (!parsed.evidence || typeof parsed.evidence !== 'string') return null;\n    if (!parsed.rationale || typeof parsed.rationale !== 'string') return null;\n    if (!ULTRAGOAL_STEERING_MUTATION_KINDS.includes(parsed.kind as UltragoalSteeringMutationKind)) return null;\n    if (!ULTRAGOAL_STEERING_SOURCES.includes(parsed.source as UltragoalSteeringSource)) return null;\n    return parsed;\n  } catch {\n    return null;","sourceCodeStart":1112,"sourceCodeEnd":1148,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/ultragoal/artifacts.ts#L1112-L1148","documentation":"A required string field on an ultragoal artifact is empty or whitespace-only. assertNonEmpty trims the value and throws with the field label (e.g. 'Missing architectureInvariantGate.evidence.') whenever it is undefined/blank.","triggerScenarios":"Calling any validating writer (e.g. finalize/quality-gate submission) with a required string field — titles, evidence entries, sourceArtifacts entries — set to '', '   ', or undefined. Inside validateArchitectureInvariantGate it fires for each sourceArtifacts[] entry (label 'architectureInvariantGate.sourceArtifacts[]') and for invariantGate.evidence.","commonSituations":"Programmatically building a quality gate from optional data (empty strings instead of omitting fields); forms/templates that submit empty inputs; spreading partial objects with unset required fields.","solutions":["Find the field named in the message and populate it with a meaningful non-empty string","Trim-check inputs before submission: skip optional empty entries from arrays rather than including ''","If building gates programmatically, filter falsy values: arr.filter(s => s?.trim())","Add a unit test that all required gate fields are non-empty before calling finalize"],"exampleFix":"// before\nawait finalize(cwd, { gate: { architectureInvariantGate: { status: 'passed', sourceArtifacts: [''], evidence: '' , invariants: [] } } });\n\n// after\nawait finalize(cwd, { gate: { architectureInvariantGate: { status: 'passed', sourceArtifacts: ['docs/arch.md'], evidence: 'invariants verified', invariants: [] } } });","handlingStrategy":"validation","validationCode":"const clean = (arr) => (arr ?? []).map(s => s?.trim()).filter(Boolean);\nif (!evidence?.trim()) throw new Error('evidence required before finalize');","typeGuard":"function isNonEmptyString(v: unknown): v is string { return typeof v === 'string' && v.trim().length > 0; }","tryCatchPattern":null,"preventionTips":["Trim and filter every user-supplied string before building gate payloads","Drop empty optional array entries instead of submitting ''","Fail fast on blank required fields in your own form/UI layer"],"tags":["ultragoal","required-field","validation","empty-string"],"backgroundTag":"required-field-missing","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}