instructure/canvas-lms · error · GraphQL::ExecutionError
Must be logged in
Error message
Must be logged in
What it means
Raised in the RejectEnrollmentInvitation mutation when context[:current_user] is nil, meaning the GraphQL request is unauthenticated. The mutation refuses to proceed without a logged-in user before doing any enrollment lookup.
Solutions
- Authenticate the request: ensure a valid Canvas session cookie or Bearer access token is sent with the GraphQL call
- Refresh an expired session (re-login) before retrying
- For scripts, generate a developer-key/token and pass it in the Authorization header
- Check the client redirects to login when current_user is nil
Example fix
// before
fetch('/api/graphql', { method: 'POST', body }) // no auth
// after
fetch('/api/graphql', { method: 'POST', headers: { Authorization: `Bearer ${token}` }, body }) Defensive patterns
Strategy: try-catch
Validate before calling
if (!currentUser) redirectToLogin()
Type guard
function isAuthenticated(ctx) { return Boolean(ctx?.currentUser?.id) } Try / catch
try {
await rejectEnrollmentInvitation({ enrollmentUuid })
} catch (e) {
if (e.message.includes('Must be logged in')) { redirectToLogin(); return }
throw e
} Prevention
- Gate invitation-action pages behind an auth check
- Refresh expired sessions before mutating requests
- Attach valid Bearer tokens for API/GraphQL automation
- Handle 401-like GraphQL errors with a login redirect
When it happens
Trigger: Calling rejectEnrollmentInvitation without a valid session or access token; expired Canvas session; API token omitted/invalid on the GraphQL endpoint.
Common situations: Deep-linking a user to an invitation-action page after their session expired; server-side scripts calling the GraphQL endpoint without Authorization header; cookies blocked or cleared.
Related errors
- Authentication required to view other users' module progress
- Enrollment invitation not found
- Enrollment is not in invited state
- Must be logged in
- Must be logged in
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/3e3438500cd076ba.
Report an issue: GitHub.
Appendix: source
Thrown at app/graphql/mutations/reject_enrollment_invitation.rb:30
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
module Mutations
class RejectEnrollmentInvitation < BaseMutation
argument :enrollment_uuid, String, required: true
field :enrollment, Types::EnrollmentType, null: true
field :success, Boolean, null: false
def resolve(input:, **)
user = context[:current_user]
raise GraphQL::ExecutionError, I18n.t("Must be logged in") unless user
enrollment = Enrollment.where(uuid: input[:enrollment_uuid]).first
raise GraphQL::ExecutionError, I18n.t("Enrollment invitation not found") unless enrollment
# Verify the enrollment belongs to the current user
raise GraphQL::ExecutionError, I18n.t("Unauthorized") unless enrollment.user == user
# Verify the enrollment is in invited state
raise GraphQL::ExecutionError, I18n.t("Enrollment is not in invited state") unless enrollment.invited?
begin
if enrollment.reject
{
enrollment:,
success: true
}
else
{View on GitHub (pinned to 1c9f0bb801)