we-promise/sure · error · Provider::Snaptrade::ConfigurationError

SnapTrade OAuth is not configured

Error message

SnapTrade OAuth is not configured

What it means

Provider::Snaptrade.authorize_url builds the OAuth authorization redirect (authorization-code + PKCE per RFC 7636) and raises ConfigurationError when the instance has no OAuth app credentials. oauth_configured? (app/models/provider/snaptrade.rb:43) requires BOTH Rails.configuration.x.snaptrade.oauth_client_id and .oauth_client_secret, which config/initializers/snaptrade.rb:3-6 populates from ENV['SNAPTRADE_OAUTH_CLIENT_ID'/'SNAPTRADE_OAUTH_CLIENT_SECRET'] or Rails credentials dig(:snaptrade, :oauth_client_id/:oauth_client_secret). Seeing this error means neither source supplied the pair, so the SnapTrade OAuth feature is effectively disabled on this deployment.

Source

Thrown at app/models/provider/snaptrade.rb:63

    end

    def oauth_client_id
      Rails.configuration.x.snaptrade&.oauth_client_id
    end

    def oauth_client_secret
      Rails.configuration.x.snaptrade&.oauth_client_secret
    end

    # PKCE pair per RFC 7636 (S256)
    def generate_pkce
      verifier = SecureRandom.urlsafe_base64(64).delete("=")[0, 128]
      challenge = Base64.urlsafe_encode64(OpenSSL::Digest::SHA256.digest(verifier), padding: false)
      { verifier: verifier, challenge: challenge }
    end

    def authorize_url(redirect_uri:, state:, code_challenge:, scope: "read")
      raise ConfigurationError, "SnapTrade OAuth is not configured" unless oauth_configured?

      params = {
        response_type: "code",
        client_id: oauth_client_id,
        redirect_uri: redirect_uri,
        scope: scope,
        state: state,
        code_challenge: code_challenge,
        code_challenge_method: "S256"
      }
      "#{AUTHORIZE_URL}?#{params.to_query}"
    end

    def exchange_code(code:, redirect_uri:, code_verifier:)
      token_request(
        grant_type: "authorization_code",
        code: code,
        redirect_uri: redirect_uri,

View on GitHub (pinned to e69894adb9)

Solutions

  1. Register an OAuth app on dashboard.snaptrade.com and copy its client id/secret
  2. Set both SNAPTRADE_OAUTH_CLIENT_ID and SNAPTRADE_OAUTH_CLIENT_SECRET in the environment (or run 'bin/rails credentials:edit' and add snaptrade: oauth_client_id / oauth_client_secret)
  3. Restart the Rails server and any background workers so the initializer re-reads config
  4. Verify in console: Provider::Snaptrade.oauth_configured? must return true
  5. Guard the connect action with oauth_configured? and render the setup instructions instead of a 500

Example fix

# before (snaptrade_items_controller)
def oauth_start
  redirect_to Provider::Snaptrade.authorize_url(redirect_uri: oauth_callback_snaptrade_items_url, state: SecureRandom.hex(32), code_challenge: Provider::Snaptrade.generate_pkce[:challenge]), allow_other_host: true
end

# after
def oauth_start
  unless Provider::Snaptrade.oauth_configured?
    redirect_to settings_provider_path, alert: t('snaptrade_items.snaptrade.oauth_setup_step_1_html') and return
  end
  redirect_to Provider::Snaptrade.authorize_url(redirect_uri: oauth_callback_snaptrade_items_url, state: SecureRandom.hex(32), code_challenge: Provider::Snaptrade.generate_pkce[:challenge]), allow_other_host: true
end
Defensive patterns

Strategy: validation

Validate before calling

# Run before starting the OAuth flow
return unless Provider::Snaptrade.oauth_configured?

Type guard

def snaptrade_oauth_ready?
  Provider::Snaptrade.oauth_configured?
end

Try / catch

begin
  redirect_to Provider::Snaptrade.authorize_url(redirect_uri:, state:, code_challenge:)
rescue Provider::Snaptrade::ConfigurationError
  redirect_to settings_path, alert: 'SnapTrade OAuth app is not configured on this instance'
end

Prevention

When it happens

Trigger: A user clicks 'Connect via SnapTrade' and snaptrade_items_controller calls Provider::Snaptrade.authorize_url(redirect_uri:, state:, code_challenge:) on an instance where the admin never registered an OAuth app, or set only one of the two env vars, or only defined credentials without the env vars and vice versa. The raise happens before any URL is built, so the redirect action 500s.

Common situations: Fresh self-hosted install without provider setup; keys configured in .env.local for dev but missing in production; typo'd env var name (e.g. SNAPTRADE_OAUTH_CLIENTID); credentials file edited without a :snaptrade: section; Puma/sidekiq not restarted after adding the env vars.

Related errors


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