instructure/canvas-lms · error · HmacHelper::Error
invalid value for #
Error message
invalid value for #{k} What it means
After HMAC verification succeeds, extract_blob checks optional expected_values against the parsed blob and raises Error "invalid value for #{k}" when blob[k] != v. It is a post-verification semantic check that signed content matches what the caller expects.
Solutions
- Compare with the correct expected value/type for the key (strings vs integers after JSON.parse).
- Regenerate the signed payload with the expected values baked in.
- Remove the key from expected_values if it is not guaranteed stable.
- Inspect the blob (JSON.parse the json param) to see the actual value and align expectations.
Example fix
// before
extract_blob(hmac, json, { user_id: "17" })
// after
extract_blob(hmac, json, { user_id: 17 }) # match JSON-parsed type Defensive patterns
Strategy: try-catch
Validate before calling
blob = JSON.parse(json)
return nil unless expected_values.all? { |k, v| blob[k] == v } Try / catch
begin
blob = extract_blob(hmac, json, expected)
rescue HmacHelper::Error => e
Rails.logger.warn("blob expected-values mismatch: #{e.message}")
return nil
end Prevention
- Match expected value types to what JSON.parse returns
- Only assert expected_values on keys guaranteed stable in the signed payload
- Regenerate signatures when the embedded values change
When it happens
Trigger: Calling extract_blob(hmac, json, {course_id: 42}) where the signed blob contains a different or missing course_id — e.g. reusing a signed URL for another course, or comparing string '42' vs integer 42.
Common situations: Bookmarked/forwarded signed links used in a different account/course context; type mismatches after JSON round-trips; secret rotation making the blob valid but stale.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- A course did not pass validation
- A # user did not pass validation (user: # , # : # , error…
- A maximum of 50 assessees can be provided at once
- A maximum of 50 assessors can be provided at once
- A (templated) course did not pass validation
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/6b310529ed564b5d.
Report an issue: GitHub.
Appendix: source
Thrown at app/helpers/hmac_helper.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 HmacHelper
# returns parsed json after verification
def extract_blob(hmac, json, expected_values = {})
unless Canvas::Security.verify_hmac_sha1(hmac, json)
raise Error, "signature doesn't match."
end
blob = JSON.parse(json)
expected_values.each do |k, v|
raise Error, "invalid value for #{k}" if blob[k] != v
end
blob
end
class Error < StandardError; end
end
View on GitHub (pinned to 1c9f0bb801)