instructure/canvas-lms · warning
Invalid action.
Error message
Invalid action.
What it means
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.
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
Example fix
// before
fetch(url, { method: 'POST', body: { action: 'like' } })
// after
fetch(url, { method: 'POST', body: { action: 'reset_like' } }) Defensive patterns
Strategy: validation
Validate before calling
const VALID_ACTIONS = ['reset_like', 'disable_summary']
if (!VALID_ACTIONS.includes(action)) throw new Error(`unsupported action: ${action}`) Type guard
const isValidAction = (a) => ['reset_like','disable_summary'].includes(a)
Try / catch
const res = await fetch(url, opts)
if (res.status === 400) {
const body = await res.json()
if (body.error === 'Invalid action.') console.error('fix action param:', action)
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Cannot change locked status on granular permission
- GUID is invalid: #
- invalid calculation_int: #
- invalid calculation_method: #
- invalid description value: #
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/26aa46962bfd9785.
Report an issue: GitHub.
Appendix: source
Thrown at app/controllers/discussion_topics_api_controller.rb:334
InstStatsd::Statsd.distributed_increment("discussion_topic.summary.feedback.disliked")
when :add_comment
render(json: { error: t("Comment is required.") }, status: :bad_request) and return if params[:comment].blank?
begin
feedback.add_comment(params[:comment])
rescue ActiveRecord::RecordInvalid => e
render(json: { error: e.message }, status: :bad_request) and return
end
InstStatsd::Statsd.distributed_increment("discussion_topic.summary.feedback.comment_added")
when :reset_like
feedback.reset_like
InstStatsd::Statsd.distributed_increment("discussion_topic.summary.feedback.reset_like")
when :disable_summary
feedback.disable_summary
InstStatsd::Statsd.distributed_increment("discussion_topic.summary.feedback.disabled")
else
logger.warn("Invalid discussion topic summary feedback action: #{action}")
render(json: { error: "Invalid action." }, status: :bad_request) and return
end
render(json: { liked: feedback.liked, disliked: feedback.disliked, comment: feedback.comment })
end
def insight
return render_unauthorized_action unless @topic.user_can_access_insights?(@current_user)
insight = @topic.insights.order(created_at: :desc).first
if insight.nil?
return render(json: { workflow_state: nil })
end
data = {
workflow_state: insight.workflow_state,
}
if DiscussionTopicInsight::TERMINAL_WORKFLOW_STATES.include?(insight.workflow_state)View on GitHub (pinned to 1c9f0bb801)