instructure/canvas-lms · error · InvalidDataError
Outcome with canvas id
Error message
Outcome with canvas id "%{id}" not found What it means
find_prior_outcome resolves vendor_guids of the form 'canvas_outcome:<id>' to an existing LearningOutcome by primary key. If LearningOutcome.find raises ActiveRecord::RecordNotFound, the import converts it to this InvalidDataError. Note the message interpolates outcome[:canvas_id] rather than the matched canvas_id, so it can render blank; the guid in the row is the id to check.
Solutions
- Verify the canvas id exists (GET /api/v1/outcomes/:id) and correct the vendor_guid.
- If the outcome was deleted, remove the row or change to a new vendor_guid so the outcome is created fresh.
- If migrating between instances, replace canvas_outcome:<id> refs with real vendor_guids instead of internal ids.
Example fix
// before "vendor_guid": "canvas_outcome:99999" // nonexistent // after "vendor_guid": "canvas_outcome:1234" // existing outcome id
Defensive patterns
Strategy: validation
Validate before calling
// Ruby: verify the canvas id exists before import if (m = /canvas_outcome:(\d+)/.match(guid)) raise 'missing outcome' unless LearningOutcome.where(id: m[1]).exists? end
Try / catch
begin
importer.import_object(...)
rescue Outcomes::Import::InvalidDataError => e
raise unless e.message.include?('not found')
# drop or recreate the row with a fresh vendor_guid
end Prevention
- Never reference internal canvas ids across Canvas instances/shards.
- Re-verify canvas_outcome: ids after deletions or migrations.
- Prefer stable external vendor_guids over canvas_outcome:<id> references.
When it happens
Trigger: A vendor_guid like 'canvas_outcome:12345' where no LearningOutcome with id 12345 exists (deleted outcome, wrong shard, or fabricated id); hit in find_prior_outcome (lib/outcomes/import.rb:245), called by import_outcome.
Common situations: Re-importing an export after the referenced outcome was deleted; exporting from one Canvas instance and importing into another where ids differ; hand-crafted import files with guessed ids.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- Outcome group with canvas id
- A cross-listing referenced a non-existent section #
- A student referenced a non-existent user #
- Can't delete a non-existent observer for observer: #
- Cannot modify outcome from another context
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/61a33579bf6fa2d9.
Report an issue: GitHub.
Appendix: source
Thrown at lib/outcomes/import.rb:245
prior
else
current
end
end
def non_vendor_guid_changes?(model)
model.has_changes_to_save? && !(model.changes_to_save.length == 1 &&
model.changes_to_save.key?("vendor_guid"))
end
def find_prior_outcome(outcome)
match = /canvas_outcome:(\d+)/.match(outcome[:vendor_guid])
if match
canvas_id = match[1]
begin
LearningOutcome.find(canvas_id)
rescue ActiveRecord::RecordNotFound
raise InvalidDataError, I18n.t(
'Outcome with canvas id "%{id}" not found',
id: outcome[:canvas_id]
)
end
else
vendor_guid = outcome[:vendor_guid]
prior = LearningOutcome.where(vendor_guid:).active_first.first
return prior if prior
LearningOutcome.new(vendor_guid:)
end
end
def find_prior_group(group, group_context)
vendor_guid = group[:vendor_guid]
prior = LearningOutcomeGroup.where(context: group_context).where(vendor_guid:).active_first.first
return prior if prior
View on GitHub (pinned to 1c9f0bb801)