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

  1. Compare with the correct expected value/type for the key (strings vs integers after JSON.parse).
  2. Regenerate the signed payload with the expected values baked in.
  3. Remove the key from expected_values if it is not guaranteed stable.
  4. 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

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


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)