{"record":{"id":"84970f2994a04288","repo":"instructure/canvas-lms","slug":"invalid-value-for-form-value","errorCode":null,"errorMessage":"Invalid value for form: #{value}","messagePattern":"Invalid value for form: #(.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"app/models/accessibility/rules/headings_start_at_h2_rule.rb","lineNumber":52,"sourceCode":"          label: I18n.t(\"How would you like to proceed?\"),\n          undo_text: I18n.t(\"Reformatted\"),\n          value: I18n.t(\"Change heading level to Heading 2\"),\n          action: I18n.t(\"Reformat\"),\n          options: [\n            I18n.t(\"Change heading level to Heading 2\"),\n            I18n.t(\"Turn into a paragraph\")\n          ]\n        )\n      end\n\n      def fix!(elem, value)\n        case value\n        when I18n.t(\"Change heading level to Heading 2\")\n          elem.name = \"h2\"\n        when I18n.t(\"Turn into a paragraph\")\n          elem.name = \"p\"\n        else\n          raise ArgumentError, \"Invalid value for form: #{value}\"\n        end\n        { changed: elem }\n      end\n\n      def display_name\n        I18n.t(\"Heading levels should start at level 2\")\n      end\n\n      def message\n        I18n.t(\n          \"This text is styled as a Heading 1, but there should only be one H1 on a web page — the page title. \" \\\n          \"Use Heading 2 or lower (H2, H3, etc.) for your content headings instead.\"\n        )\n      end\n\n      def why\n        [\n          I18n.t(","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/models/accessibility/rules/headings_start_at_h2_rule.rb#L34-L70","documentation":"HeadingsStartAtH2Rule#fix! only accepts values equal to the translated strings 'Change heading level to Heading 2' or 'Turn into a paragraph' and rewrites the element tag accordingly. Any other value raises ArgumentError 'Invalid value for form: ...' since the fixer cannot infer the intended transformation.","triggerScenarios":"Calling fix! with a value that doesn't byte-equal the current I18n.t translations, e.g. hard-coded English strings in a non-English locale, or a value key like 'h2' instead of the label; locale changed between form render and submission.","commonSituations":"Locale mismatch: page rendered in English, submitted under a different I18n.locale (per-user locale), so value compares false; tests passing raw English labels while specs run in another locale; API clients sending semantic values instead of labels.","solutions":["Pass the exact I18n.t('Change heading level to Heading 2') or I18n.t('Turn into a paragraph') string as value, computed in the same locale as the request","Better: compare against stable keys instead of translated labels (refactor the rule to accept 'h2'/'p')","Ensure I18n.locale is consistent between rendering the fix form and processing fix!","Rescue ArgumentError and return a 400 with the accepted options"],"exampleFix":"// before\nrule.fix!(elem, 'Change heading level to Heading 2') # fails in non-en locale\n// after\nrule.fix!(elem, I18n.t('Change heading level to Heading 2'))","handlingStrategy":"validation","validationCode":"// send stable keys, compare in the same locale\nconst accepted = [I18n.t('Change heading level to Heading 2'), I18n.t('Turn into a paragraph')];\nif (!accepted.includes(value)) return alert('Invalid option');","typeGuard":null,"tryCatchPattern":"begin\n  rule.fix!(elem, value)\nrescue ArgumentError => e\n  render json: { error: e.message, accepted: ['h2','p'] }, status: :bad_request\nend","preventionTips":["Never hard-code English labels in clients; compute via I18n.t at submit time","Pin I18n.locale for the request lifecycle (render + submit in same locale)","Refactor the rule to accept semantic keys ('h2'/'p') rather than translated strings"],"tags":["accessibility","i18n","validation"],"backgroundTag":"invalid-argument-value","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"}