instructure/canvas-lms · error
unable to handle state change: #
Error message
unable to handle state change: #{asked_state} What it means
CreateAssignment mutation's resolve maps an asked state ('unpublished'/'published') into input_hash[:published]; any other value falls through to this raise. It is an internal exhaustive-case guard for the requested workflow state.
Solutions
- Only send 'published' or 'unpublished' as the state in createAssignment
- Use the same enum type declared in the mutation's input so GraphQL rejects invalid values at validation time
- Update the mutation to raise GraphQL::ExecutionError with the offending value for clearer client errors
Example fix
# before
raise "unable to handle state change: #{asked_state}"
# after
raise GraphQL::ExecutionError, "unable to handle state change: #{asked_state}" Defensive patterns
Strategy: validation
Validate before calling
const allowedStates = ['published', 'unpublished'];
if (state && !allowedStates.includes(state)) {
throw new Error(`state must be one of ${allowedStates.join(', ')}`);
} Type guard
function isCreateState(s) {
return s === 'published' || s === 'unpublished';
} Try / catch
try {
await createAssignment({ state });
} catch (e) {
if (/unable to handle state change/.test(e.message)) {
showError('Unsupported state for assignment creation; use published or unpublished.');
}
} Prevention
- Type the state input as a GraphQL enum limited to create-valid values
- Share state constants between client and server code
- Do not reuse update-mutation state values (e.g. 'deleted') for create
- Add client-side schema validation of mutation variables
When it happens
Trigger: Passing a state input value other than published/unpublished (e.g. 'deleted', 'draft', or a typo like 'publish') when creating an assignment via GraphQL.
Common situations: Clients copying state values from the update mutation (which accepts 'deleted') into the create mutation; enum typos in GraphQL variables.
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
- unable to handle state change: #
- All ConversationMessages must exist within the same…
- An unexpected error occurred while grading.
- An unexpected error occurred while submitting feedback.
- Assignment group category id and discussion topic group…
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/b40ee972380b9535.
Report an issue: GitHub.
Appendix: source
Thrown at app/graphql/mutations/create_assignment.rb:48
course_id = GraphQLHelpers.parse_relay_or_legacy_id(input[:course_id], "Course")
@course = Course.find_by(id: course_id)
@working_assignment = @course.assignments.build if @course
raise GraphQL::ExecutionError, "invalid course: #{course_id}" unless @working_assignment&.grants_right? current_user, :create
# initialize published argument
@working_assignment.workflow_state = "unpublished"
input_hash = input.to_h
if input_hash.key? :state
asked_state = input_hash.delete :state
case asked_state
when "unpublished"
input_hash[:published] = false
when "published"
input_hash[:published] = true
else
raise "unable to handle state change: #{asked_state}"
end
end
if submittable
submittable.assignment = @working_assignment
end
api_proxy = ApiProxy.new(context[:request], @working_assignment, context[:session], current_user, in_app: context[:in_app])
validate_for_checkpoints(input_hash)
if input_hash[:for_checkpoints]
@working_assignment.has_sub_assignments = true
end
# modifies input_hash
prepare_input_params!(input_hash, api_proxy)
module_ids = prepare_module_ids!(input_hash)View on GitHub (pinned to 1c9f0bb801)