we-promise/sure · error · Error

Could not save that passkey or security key. Please try agai

Error message

Could not save that passkey or security key. Please try again.

What it means

Raised when JSON.parse of the Yahoo Finance HTTP body raises JSON::ParserError inside the chart-prices path (and identically for security info at app/models/provider/yahoo_finance.rb:283). The body was not valid JSON — typically an HTML error page (consent wall, CAPTCHA, 'Unable to process request'), an empty body from a proxy/429, or a gzipped/truncated response. The rescue re-wraps the parser message into the provider's generic Error, so the original body is lost unless logged before parsing.

Source

Thrown at app/javascript/controllers/webauthn_registration_controller.js:44

      const options = await this.fetchOptions();
      const credential = await navigator.credentials.create({
        publicKey: prepareCredentialCreationOptions(options),
      });

      await this.createCredential(serializePublicKeyCredential(credential));
    } catch (error) {
      this.showError(error.message);
    }
  }

  async fetchOptions() {
    const response = await fetch(this.optionsUrlValue, {
      method: "POST",
      headers: this.headers,
      credentials: "same-origin",
    });

    if (!response.ok) throw new Error(await this.errorMessage(response));

    return response.json();
  }

  async createCredential(credential) {
    const response = await fetch(this.createUrlValue, {
      method: "POST",
      headers: this.headers,
      credentials: "same-origin",
      body: JSON.stringify({
        credential,
        webauthn_credential: {
          nickname: this.hasNicknameTarget ? this.nicknameTarget.value : "",
        },
      }),
    });

    if (!response.ok) throw new Error(await this.errorMessage(response));

View on GitHub (pinned to e69894adb9)

Solutions

  1. Log response.status and a truncated response.body before JSON.parse to see what Yahoo actually returned
  2. On 429/backoff, retry with exponential backoff and throttle_request spacing honored
  3. Refresh cookie/crumb (clear_crumb_cache + fetch_cookie_and_crumb) before retrying, since stale auth often yields HTML
  4. Ensure Faraday adapter/middleware handles gzip and does not follow redirects to HTML error pages
  5. If IP is Yahoo-blocked (datacenter range), route via a different provider or egress IP

Example fix

# before
data = JSON.parse(response.body)

# after
raise Error, "Yahoo returned HTTP #{response.status} (non-JSON body)" unless response.success?
data = begin
  JSON.parse(response.body)
rescue JSON::ParserError => e
  Rails.logger.error("Non-JSON Yahoo body: #{response.body.to_s[0, 200]}")
  raise Error, "Invalid response format: #{e.message}"
end
Defensive patterns

Strategy: retry

Try / catch

attempts = 0
begin
  attempts += 1
  prices = provider.fetch_security_prices(symbol: s, start_date: a, end_date: b)
rescue Provider::YahooFinance::Error => e
  raise unless e.message.start_with?("Invalid response format") && attempts < 3
  provider.send(:clear_crumb_cache) if provider.respond_to?(:clear_crumb_cache)
  sleep(2**attempts)
  retry
end

Prevention

When it happens

Trigger: Yahoo responds with an HTML rate-limit/consent page instead of the v8 chart JSON; a CDN or corporate proxy strips the body or returns an error page; response body truncated (connection reset mid-transfer); stale crumb causing a redirect to an HTML login page that gets parsed as JSON.

Common situations: Scraping Yahoo from datacenter IPs that hit their consent/CAPTCHA wall; Faraday middleware misconfiguration (missing gzip decompression); running syncs through a proxy that injects an HTML block page; after Yahoo changes endpoint behavior the authenticated client follows a redirect chain ending in HTML.

Related errors


AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21). Data as JSON: /api/errors/6db69741afb9984f. Report an issue: GitHub.