Skip to content

fix(forecast,twist): https base_uri so writes don't die on the http->https redirect - #164

Merged
hhff merged 1 commit into
mainfrom
fix/forecast-https-base-uri
Jul 31, 2026
Merged

fix(forecast,twist): https base_uri so writes don't die on the http->https redirect#164
hhff merged 1 commit into
mainfrom
fix/forecast-https-base-uri

Conversation

@hhff

@hhff hhff commented Jul 31, 2026

Copy link
Copy Markdown
Member

The bug

Stacks::Forecast declared base_uri 'api.forecastapp.com'no scheme, so HTTParty defaulted to http://. Forecast 301-redirects http → https. GETs survive the redirect (reads worked), but a redirected POST arrives malformed and Forecast returns 400 Bad Request. So:

  • create_assignment raised on the 400, and RecurringAssignment#materialize!'s per-occurrence rescue => e; Sentry.capture_exception(e) swallowed it — no occurrence recorded, no Forecast assignment, nothing in the admin UI.
  • This affects every Forecast write through the class: recurring-assignment materialization, the provisioning tools (create project/client/workstream/rate), and the write-through work. It passed CI the whole time because the tests stub the HTTP layer — it only surfaces against the live API.

Verified live (against the real account)

Request Result
via the class (http → 301 → https) 400 Bad Request (malformed)
direct https://…/assignments, same body/headers 201 Created

The fix

One line each: base_uri 'https://api.forecastapp.com' and — same scheme-less pattern, also a writer — base_uri 'https://api.twist.com/api/v3'. Every other API client (Runn, Deel, Notion, Apollo) already used https://.

Added test/lib/stacks/https_base_uri_test.rb — a guard that fails if any HTTParty client's base_uri isn't https://, so this silent-write-failure class can't return.

Testing

Guard test fails on the old code (got "http://api.forecastapp.com"), passes after. Full test/lib/stacks suite green (284 runs, 0 failures). No behavior change for reads; writes now hit https directly instead of a mangling redirect.

🤖 Generated with Claude Code

…https redirect

Stacks::Forecast declared base_uri 'api.forecastapp.com' (no scheme), so
HTTParty used http://. Forecast 301-redirects to https; GETs survive that
but a redirected POST arrives malformed and Forecast returns 400. Reads
worked, writes silently failed — create_assignment raised the 400 and
RecurringAssignment#materialize! swallowed it (Sentry), so nothing reached
Forecast and nothing surfaced in the UI. Verified live: via the class
(http->301->https) POST /assignments => 400; direct https => 201.

Stacks::Twist had the same scheme-less base_uri and also POSTs — fixed for
the same reason. All other API clients already used https.

Added a guard test pinning every HTTParty client to an https base_uri.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@hhff
hhff merged commit 15b11e9 into main Jul 31, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant