{"record":{"id":"19ba8215122a3a87","repo":"instructure/canvas-lms","slug":"caption-cannot-be-empty","errorCode":null,"errorMessage":"Caption cannot be empty.","messagePattern":"Caption cannot be empty\\.","errorType":"validation","errorClass":"StandardError","httpStatus":null,"severity":"error","filePath":"app/models/accessibility/rules/table_caption_rule.rb","lineNumber":48,"sourceCode":"\n        caption = elem.query_selector(\"caption\")\n\n        I18n.t(\"Table caption should be present.\") if !caption || caption.text.gsub(/[[:space:]]/, \"\") == \"\"\n      end\n\n      def form(_elem)\n        Accessibility::Forms::TextInputField.new(\n          label: I18n.t(\"Table caption\"),\n          undo_text: I18n.t(\"Caption added\"),\n          value: \"\",\n          action: I18n.t(\"Add caption\"),\n          can_generate_fix: true,\n          generate_button_label: I18n.t(\"Generate\")\n        )\n      end\n\n      def fix!(elem, value)\n        raise StandardError, \"Caption cannot be empty.\" if value.blank?\n\n        caption = elem.at_css(\"caption\")\n        unless caption\n          caption = elem.document.create_element(\"caption\")\n          TableCaptionRuleHelper.prepend(elem, caption)\n        end\n        caption.content = value\n        { changed: elem }\n      end\n\n      def display_name\n        I18n.t(\"Missing table caption\")\n      end\n\n      def message\n        I18n.t(\"Tables should include a caption describing the contents of the table.\")\n      end\n","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/models/accessibility/rules/table_caption_rule.rb#L30-L66","documentation":"TableCaptionRule#fix! adds or updates a <caption> for a data table, but refuses to proceed when the provided caption value is blank, raising StandardError 'Caption cannot be empty.' A caption is required content for the fix, so an empty value cannot produce a valid accessibility correction.","triggerScenarios":"Calling fix!(elem, nil) or fix!(elem, '') or whitespace-only value on a table element; the a11y fixer UI submits the caption form with an empty text box.","commonSituations":"User clicks 'Generate'/'Apply' in the table caption fix dialog without typing; automated batch applying caption fixes with missing data; form reset clearing the input before submit.","solutions":["Supply a non-blank caption string describing the table's purpose","Disable the apply button until input is non-empty on the client","If the table is layout-only, use a different rule (presentation role) instead of an empty caption","Rescue StandardError around fix! and show the validation message"],"exampleFix":"// before\nrule.fix!(table_elem, params[:caption]) # caption may be ''\n// after\nraise ValidationError, msg unless params[:caption].present?\nrule.fix!(table_elem, params[:caption])","handlingStrategy":"validation","validationCode":"if (!caption || !caption.trim()) {\n  alert('Caption cannot be empty'); return;\n}\nrule.fix!(tableElem, caption)","typeGuard":"const hasCaption = (v) => typeof v === 'string' && v.trim().length > 0","tryCatchPattern":"begin\n  rule.fix!(elem, value)\nrescue StandardError => e\n  render json: { error: e.message }, status: :unprocessable_entity\nend","preventionTips":["Disable the apply/Generate button until caption input has content","Suggest an auto-generated caption draft users can edit","Decide layout tables shouldn't use this fix path"],"tags":["accessibility","validation","ruby"],"backgroundTag":"empty-required-field","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}