we-promise/sure · error · Provider::Questrade::Error
not_found
not_found
Error message
Resource not found
What it means
Raised by Provider::Questrade#handle_response on HTTP 404: the path under api_server does not exist. Because api_server is a per-session host returned by the token exchange, a 404 usually means the path is malformed (bad account_id interpolation) or the api_server value is stale/wrong (e.g. missing a trailing segment or pointing at a retired host), rather than the account being absent (Questrade typically 403s foreign accounts).
Source
Thrown at app/models/provider/questrade.rb:258
source: self.class.name,
provider_key: "questrade",
metadata: { status: response.code, body: response.body.to_s.first(1000) }
)
end
def handle_response(response)
case response.code
when 200, 201
JSON.parse(response.body, symbolize_names: true)
when 400
capture_response_error("bad_request", response)
raise Error.new("Questrade bad request (#{response.code})", :bad_request)
when 401
raise AuthenticationError.new("Invalid or expired Questrade credentials", :unauthorized)
when 403
raise AuthenticationError.new("Access forbidden - check your permissions", :access_forbidden)
when 404
raise Error.new("Resource not found", :not_found)
when 429
raise RetryableResponseError.new("Questrade rate limit exceeded. Please try again later.", :rate_limited)
when 500..599
raise RetryableResponseError.new("Questrade server error (#{response.code}). Please try again later.", :server_error)
else
capture_response_error("unexpected_response", response)
raise Error.new("Questrade unexpected response (#{response.code})", :unknown)
end
end
end
View on GitHub (pinned to e69894adb9)
Solutions
- Log the full URL being requested and compare with one captured from a working session.
- Verify account_id is non-blank and comes from list_accounts output before interpolating it.
- Force a fresh exchange (drop the cached api_server) so the client gets the currently valid per-session host.
- Check Questrade API docs for endpoint removals if the path itself 404s with a known-good host.
Example fix
# before
provider.get_holdings(account_id: account.display_number) # wrong id -> 404
# after
api_id = provider.list_accounts[:accounts]
.find { |a| a[:number] == account.display_number }&.dig(:number)
raise ArgumentError, "account not found via list_accounts" if api_id.blank?
provider.get_holdings(account_id: api_id) Defensive patterns
Strategy: validation
Validate before calling
raise ArgumentError, "account_id required" if account_id.to_s.strip.blank? account_id = account_id.to_s.strip # and never hand-edit the persisted api_server string
Try / catch
begin
provider.get_holdings(account_id: id)
rescue Provider::Questrade::Error => e
if e.error_type == :not_found
provider.exchange_token! # refresh per-session api_server host, then retry once
retry
end
raise
end Prevention
- Always source account IDs from list_accounts output, never the web dashboard.
- When a 404 appears for everything, suspect the stored api_server before the IDs.
When it happens
Trigger: get_holdings/get_balances with a nil or malformed account_id producing 'v1/accounts//positions'; api_server persisted without its path prefix or with a typo after the exchange; calling a v1 endpoint that Questrade retired; using api_base before it ends with '/' (the method normalizes this, but bypassing it breaks paths).
Common situations: account_id stored as the display number instead of the API id; manual edits to the persisted api_server string; Questrade migrating api_server hosts for new sessions while old ones are cached indefinitely.
Related errors
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/d803c0397ee1ae67.
Report an issue: GitHub.