Follow-up from #1080. /jobs/match is 503-gated by JOB_MATCH_ENABLED and the default is OFF in production today. With the current code, every visit to the Matches tab returns 503 and surfaces a generic "Failed to load matches" instead of the backend's intentional product copy.
Two acceptable fixes (per spec)
Option A — hide the tab until the flag is on (recommended).
- On first jobs-page mount,
POST /jobs/match once and inspect the response.
- If 503 with
code: "SERVICE_UNAVAILABLE", cache the verdict in component state and don't render the Matches tab button at all.
- Surface resume scoring + tailoring on the Jobs page in its place.
Option B — render the 503 message verbatim.
- Fix
JobMatch.tsx:33 — the 503 body is {error: {code, message, request_id}}. The current code does errData.error || "Failed to load matches" which renders [object Object] or falls back to the generic string.
- Read
errData.error?.message and render it directly. The text is intentional product copy: "Job matching is not yet available. We're sourcing real postings; in the meantime use /jobs/resume/score for resume coaching."
Acceptance
- A user with the flag off either does not see a Matches tab, or sees the operator-friendly message — never a generic error.
- The fix doesn't break behavior once the flag flips on.
Follow-up from #1080.
/jobs/matchis 503-gated byJOB_MATCH_ENABLEDand the default is OFF in production today. With the current code, every visit to the Matches tab returns 503 and surfaces a generic "Failed to load matches" instead of the backend's intentional product copy.Two acceptable fixes (per spec)
Option A — hide the tab until the flag is on (recommended).
POST /jobs/matchonce and inspect the response.code: "SERVICE_UNAVAILABLE", cache the verdict in component state and don't render the Matches tab button at all.Option B — render the 503 message verbatim.
JobMatch.tsx:33— the 503 body is{error: {code, message, request_id}}. The current code doeserrData.error || "Failed to load matches"which renders[object Object]or falls back to the generic string.errData.error?.messageand render it directly. The text is intentional product copy: "Job matching is not yet available. We're sourcing real postings; in the meantime use /jobs/resume/score for resume coaching."Acceptance