instructure/canvas-lms · error · GraphQL::ExecutionError
Outcome is not available in context #
Error message
Outcome %{outcome_id} is not available in context %{context_type}#%{context_id} What it means
Raised in SetFriendlyDescriptionMutation#validate! after permission checks pass, when context.available_outcome(outcome.id, allow_global: true) returns nil. This means the outcome being given a friendly description is not part of the context's available outcome set (course/account outcome tree, even counting global outcomes), so the mutation refuses to attach a friendly description in that context.
Solutions
- Verify the outcome is actually available in the target context (Course#available_outcome / account outcome tree) and use an outcome that is linked there
- Check the outcome_id/context pairing: ensure you are passing the context where the outcome was imported or linked
- If the outcome should be available, add it to the context (import/link the outcome into the course or account) and retry
- Restore or re-add the outcome if it was deleted or unlinked from the context's outcome tree
Example fix
// before: blindly calling with any outcome id
setFriendlyDescription(input: { contextId, contextType: 'Course', outcomeId, description })
// after: pre-check availability in context
const outcome = course.outcomes.find(o => o.id === outcomeId);
if (!outcome) throw new Error(`outcome ${outcomeId} not available in course ${contextId}`);
setFriendlyDescription(input: { contextId, contextType: 'Course', outcomeId, description }); Defensive patterns
Strategy: validation
Validate before calling
async function assertOutcomeInContext(contextType, contextId, outcomeId) {
const endpoint = contextType === 'Account'
? `/api/v1/accounts/${contextId}/outcomes?outcome_ids[]=${outcomeId}`
: `/api/v1/courses/${contextId}/outcome_group_links`;
const res = await fetch(endpoint);
const data = await res.json();
const linked = Array.isArray(data)
? data.some(l => l?.outcome?.id === outcomeId)
: (data?.outcome_groups || []).some(g => (g.outcomes || []).some(o => o.id === outcomeId));
if (!linked) throw new Error(`Outcome ${outcomeId} not available in ${contextType} ${contextId}`);
} Type guard
const hasLinkedOutcome = (outcomeLinks, outcomeId) => Array.isArray(outcomeLinks) && outcomeLinks.some(l => Number(l?.outcome?.id) === Number(outcomeId));
Try / catch
try {
await setFriendlyDescription({ variables: { contextType, contextId, outcomeId, description } });
} catch (e) {
if (e.message.includes('is not available in context')) {
showBanner('This outcome is not linked to this course/account.');
} else { throw e; }
} Prevention
- Source outcomeIds from the same context's outcome list, never from a different course or environment
- Re-fetch outcome links after imports/copies or outcome deletions instead of caching ids
- Keep the outcomeId and contextType/contextId pair from the same UI selection event
- Prefer global friendly descriptions only for outcomes genuinely available globally
When it happens
Trigger: Calling the setFriendlyDescription mutation with an outcomeId that is not linked/available in the given context (context_type + context_id): an outcome from another course/account, a deleted or unlinked outcome, or an outcome id supplied for the wrong context entirely.
Common situations: Frontend passing an outcome id from a different course after a copy/import; outcomes removed from an account's outcome tree while a stale UI still references them; global outcomes used with a context whose account chain does not include them; scripts iterating outcome ids from one environment against another.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Outcome is not available in context #
- Auto-grading failed due to the following issue(s): #
- cannot import a root group
- group not found
- invalid context for group
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/45428140d5b0cbde.
Report an issue: GitHub.
Appendix: source
Thrown at app/graphql/mutations/set_friendly_description.rb:77
friendly_description.save!
else
friendly_description.destroy if friendly_description.persisted?
friendly_description.description = ""
end
{
outcome_friendly_description: friendly_description
}
end
private
def validate!(context, outcome)
verify_authorized_action!(context, :manage_outcomes)
unless context.available_outcome(outcome.id, allow_global: true)
raise GraphQL::ExecutionError, I18n.t(
"Outcome %{outcome_id} is not available in context %{context_type}#%{context_id}",
outcome_id: outcome.id.to_s,
context_id: context.id.to_s,
context_type: context.class.name
)
end
end
def get_context(context_type, context_id)
unless VALID_CONTEXTS.include?(context_type)
raise GraphQL::ExecutionError, I18n.t("Invalid context type")
end
context_type.constantize.find_by(id: context_id).tap do |context|
unless context
raise GraphQL::ExecutionError, I18n.t(
"No such context for %{context_type}#%{context_id}",
context_type:,View on GitHub (pinned to 1c9f0bb801)