instructure/canvas-lms · error

GUID is invalid: #

Error message

GUID is invalid: #{guid}

What it means

OutcomesAcademicBenchmarkImportApiController#valid_guid validates Academic Benchmark GUID parameters against the 8-4-4-4-12 hex pattern and raises when the supplied guid is malformed. GUIDs must be UUID-like strings identifying the outcome document to import.

Solutions

  1. Send the full 36-character hex UUID, e.g. A833C528-901A-11DF-A622-0C319DFF4B22.
  2. Strip whitespace and URL-decode the guid before sending.
  3. Verify you are using the Academic Benchmark GUID field, not an internal numeric id.
  4. Validate client-side with a UUID regex before calling the endpoint.

Example fix

// before
params[:guid] = "12345"
// after
params[:guid] = "A833C528-901A-11DF-A622-0C319DFF4B22"
Defensive patterns

Strategy: validation

Validate before calling

def valid_ab_guid?(guid)
  /[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}/i.match?(guid.to_s.strip)
end

Try / catch

begin
  import_outcomes(guid: guid)
rescue RuntimeError => e
  raise InvalidGuidParameter, guid if e.message.start_with?('GUID is invalid:')
  raise
end

Prevention

When it happens

Trigger: Calling the academic benchmark import API with a guid that is not a hex UUID (e.g. 'abc', a numeric id, empty string, or truncated UUID).

Common situations: Client passes the Academic Benchmark outcome description/id instead of the GUID; GUIDs copied with lowercase is fine (regex is /i) but with extra whitespace or URL-encoding artifacts fail; swapped params put an integer where the guid belongs.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/8d4f641bbc6b26bc. Report an issue: GitHub.

Appendix: source

Thrown at app/controllers/outcomes_academic_benchmark_import_api_controller.rb:92

  def has_api_config
    err = AcademicBenchmark.check_config
    if err.nil?
      true
    else
      render json: { error: "The AcademicBenchmark API is not configured #{err}" }
      false
    end
  end

  ##
  # valid guids can only contain hex digits (letters all upper case),
  # and must be separated between a '-' [8-4-4-4-12]
  #
  #   example:  A833C528-901A-11DF-A622-0C319DFF4B22
  ##
  def valid_guid(guid)
    unless /[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}/i.match?(guid)
      raise "GUID is invalid: #{guid}"
    end
  end

  def parse_int(value)
    Integer value
  rescue
    raise "invalid value, must be integer: #{value}"
  end

  def valid_options(hash)
    options = {}
    if hash.key? :calculation_method
      options[:calculation_method] = parse_calculation_method hash[:calculation_method]
      options[:calculation_int] = parse_calculation_int options[:calculation_method], hash[:calculation_int]
    end
    options[:mastery_points] = parse_int hash[:mastery_points] if hash.key? :mastery_points
    options[:points_possible] = parse_int hash[:points_possible] if hash.key? :points_possible
    unless hash[:ratings].nil?

View on GitHub (pinned to 1c9f0bb801)