{"record":{"id":"26aa46962bfd9785","repo":"instructure/canvas-lms","slug":"invalid-action","errorCode":null,"errorMessage":"Invalid action.","messagePattern":"Invalid action\\.","errorType":"http","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"app/controllers/discussion_topics_api_controller.rb","lineNumber":334,"sourceCode":"      InstStatsd::Statsd.distributed_increment(\"discussion_topic.summary.feedback.disliked\")\n    when :add_comment\n      render(json: { error: t(\"Comment is required.\") }, status: :bad_request) and return if params[:comment].blank?\n\n      begin\n        feedback.add_comment(params[:comment])\n      rescue ActiveRecord::RecordInvalid => e\n        render(json: { error: e.message }, status: :bad_request) and return\n      end\n      InstStatsd::Statsd.distributed_increment(\"discussion_topic.summary.feedback.comment_added\")\n    when :reset_like\n      feedback.reset_like\n      InstStatsd::Statsd.distributed_increment(\"discussion_topic.summary.feedback.reset_like\")\n    when :disable_summary\n      feedback.disable_summary\n      InstStatsd::Statsd.distributed_increment(\"discussion_topic.summary.feedback.disabled\")\n    else\n      logger.warn(\"Invalid discussion topic summary feedback action: #{action}\")\n      render(json: { error: \"Invalid action.\" }, status: :bad_request) and return\n    end\n\n    render(json: { liked: feedback.liked, disliked: feedback.disliked, comment: feedback.comment })\n  end\n\n  def insight\n    return render_unauthorized_action unless @topic.user_can_access_insights?(@current_user)\n\n    insight = @topic.insights.order(created_at: :desc).first\n    if insight.nil?\n      return render(json: { workflow_state: nil })\n    end\n\n    data = {\n      workflow_state: insight.workflow_state,\n    }\n\n    if DiscussionTopicInsight::TERMINAL_WORKFLOW_STATES.include?(insight.workflow_state)","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/controllers/discussion_topics_api_controller.rb#L316-L352","documentation":"DiscussionTopicsApiController#summary_feedback dispatches on an :action param (e.g. reset_like, disable_summary). Any action value outside the known case branches falls into the else, logs a warning, and renders a 400 JSON body { error: \"Invalid action.\" } rather than raising.","triggerScenarios":"POSTing/PATCHing to the summary feedback endpoint with an unrecognized or misspelled `action` parameter (e.g. action=like when only reset_like/disable_summary are supported, or action omitted/blank).","commonSituations":"Client/server API version drift where a client sends actions this Canvas build doesn't know; typos in integrations; automated scripts built from outdated API docs.","solutions":["Send one of the supported action values the case statement handles (e.g. :reset_like, :disable_summary)","Check the controller for the current list of valid actions for your Canvas version","Update the client integration to match the deployed Canvas API surface","If server-side, add the new action to the case statement and instrument it"],"exampleFix":"// before\nfetch(url, { method: 'POST', body: { action: 'like' } })\n// after\nfetch(url, { method: 'POST', body: { action: 'reset_like' } })","handlingStrategy":"validation","validationCode":"const VALID_ACTIONS = ['reset_like', 'disable_summary']\nif (!VALID_ACTIONS.includes(action)) throw new Error(`unsupported action: ${action}`)","typeGuard":"const isValidAction = (a) => ['reset_like','disable_summary'].includes(a)","tryCatchPattern":"const res = await fetch(url, opts)\nif (res.status === 400) {\n  const body = await res.json()\n  if (body.error === 'Invalid action.') console.error('fix action param:', action)\n}","preventionTips":["Keep client action constants in sync with the controller case list","Check the API docs for the deployed Canvas version","Handle 400 responses explicitly in integrations"],"tags":["api","validation","http-400"],"backgroundTag":"invalid-enum-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"}