instructure/canvas-lms · error · ArgumentError
Unsupported embedding version #
Error message
Unsupported embedding version #{version} What it means
SmartSearch.generate_embedding dispatches on an explicit embedding version (EMBEDDING_VERSION is 2: v1 = OpenAI ada-002 HTTP API, v2 = Bedrock cohere.embed-multilingual-v3). Passing any version other than 1 or 2 raises ArgumentError 'Unsupported embedding version'.
Solutions
- Use SmartSearch::EMBEDDING_VERSION instead of hardcoding a version literal
- Pass version: 1 or version: 2 explicitly (integers, not strings)
- If data was embedded with an older/newer version, re-index with the currently supported version
- Check for string/integer type confusion in the version parameter
Example fix
# before embedding = SmartSearch.generate_embedding(text, version: 3) # after embedding = SmartSearch.generate_embedding(text, version: SmartSearch::EMBEDDING_VERSION)
Defensive patterns
Strategy: type-guard
Validate before calling
raise ArgumentError, 'version must be 1 or 2' unless [1, 2].include?(version)
Type guard
def valid_embedding_version?(v) [1, 2].include?(v) end
Try / catch
begin
embedding = SmartSearch.generate_embedding(input, version: version)
rescue ArgumentError => e
Rails.logger.error("#{e.message}; falling back to EMBEDDING_VERSION")
embedding = SmartSearch.generate_embedding(input)
end Prevention
- Reference SmartSearch::EMBEDDING_VERSION, never hardcoded numbers
- Pass integers, not strings, for version
- Re-index stored embeddings when the supported version changes
- Test version dispatch when bumping EMBEDDING_VERSION
When it happens
Trigger: Calling SmartSearch.generate_embedding(input, version: 3) (or 0, nil, '2' as a string) — e.g. code hardcoding an old/new version instead of using the EMBEDDING_VERSION constant, or persisted records storing a version value that is no longer supported.
Common situations: Upgrading/downgrading Canvas where stored embedding versions no longer match supported ones; copy-pasted code passing literal versions; type confusion passing a string '2' instead of integer 2; testing experimental embedding models by bumping version without implementing the branch.
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
- A new_id, '# ', referenced an existing # and the # with #…
- A new_integration_id, '#
- A student referenced a non-existent user #
- A user did not pass validation
- [A11Y Scan] Skipped resource #
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/619fdad0658236bb.
Report an issue: GitHub.
Appendix: source
Thrown at lib/smart_search.rb:80
@search_info.map do |_, proc, _|
proc.call(course)
end
end
def search_scopes(course, user)
@search_info.map do |klass, _, proc|
[klass, proc.call(course, user)]
end
end
def generate_embedding(input, query: false, version: EMBEDDING_VERSION)
case version
when 1
generate_embedding_v1(input)
when 2
generate_embedding_v2(input, query)
else
raise ArgumentError, "Unsupported embedding version #{version}"
end
end
def generate_embedding_v1(input)
# NOTE: openai does not differentiate between query and document embeddings
url = "https://api.openai.com/v1/embeddings"
headers = {
"Authorization" => "Bearer #{api_key}",
"Content-Type" => "application/json"
}
data = {
input:,
model: "text-embedding-ada-002"
}
response = JSON.parse(Net::HTTP.post(URI(url), data.to_json, headers).body)
raise response["error"]["message"] if response["error"]View on GitHub (pinned to 1c9f0bb801)