{"record":{"id":"217df52e60e120ef","repo":"unionlabs/union","slug":"failed-to-check-contribution-status","errorCode":null,"errorMessage":"Failed to check contribution status","messagePattern":"Failed to check contribution status","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ceremony/src/lib/supabase/index.ts","lineNumber":128,"sourceCode":"\n    let status: ContributionState\n\n    if (isContributor && !hasSubmitted && !hasVerified) {\n      status = \"contribute\"\n    } else if (isContributor && hasSubmitted && !hasVerified) {\n      status = \"verifying\"\n    } else if (hasVerified) {\n      status = \"contributed\"\n    } else if (!hasSubmitted && isExpired) {\n      status = \"missed\"\n    } else {\n      status = \"notContributed\"\n    }\n\n    return status\n  } catch (error) {\n    console.log(\"Error checking contribution status:\", error)\n    throw new Error(\"Failed to check contribution status\")\n  }\n}\n\nexport const getCurrentUserState = async (userId: string | undefined): Promise<AllowanceState> => {\n  if (!userId) {\n    console.log(\"Need to be logged in to get allowance state\")\n    return undefined\n  }\n\n  const { data, error } = await queryCurrentUserState()\n  if (error || !data) {\n    return undefined\n  }\n\n  if (data.in_queue) {\n    return \"inQueue\"\n  }\n  if (data.has_redeemed) {","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/unionlabs/union/blob/031785bb6dc6b957c624e62bc64c184409c97d7b/ceremony/src/lib/supabase/index.ts#L110-L146","documentation":"Catch-all at the end of getContributionState: any exception thrown by the four parallel Supabase queries or the status-derivation logic is console.logged and re-thrown as this generic Error, discarding the original cause. The real reason (RLS denial, network failure, malformed data) is only visible in the preceding console.log.","triggerScenarios":"Row Level Security denying SELECT on contributor/contribution tables to the current auth.uid(); network or Supabase outage during the Promise.all; unexpected null/shape in query results breaking the status computation.","commonSituations":"RLS policies not covering a new table or role; expired/invalid JWT mid-session; schema changes after a ceremony migration.","solutions":["Check the console output for 'Error checking contribution status:' — the underlying error is printed there and names the real cause","If the cause is a JWT/auth error, refresh the session (supabase.auth.refreshSession) or re-login","Verify RLS policies grant the authenticated role SELECT on the queried tables for the user's auth.uid()","Attach the original error via { cause } (or rethrow it) so callers and logs keep the stack"],"exampleFix":"// before\n} catch (error) {\n  console.log(\"Error checking contribution status:\", error)\n  throw new Error(\"Failed to check contribution status\")\n}\n\n// after\n} catch (error) {\n  console.error(\"Error checking contribution status:\", error)\n  throw new Error(\"Failed to check contribution status\", { cause: error })\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const state = await getContributionState()\n} catch (e) {\n  if (e instanceof Error && e.message === \"Failed to check contribution status\") {\n    // the real cause was console.logged; check devtools, then:\n    await supabase.auth.refreshSession() // if JWT expiry is the cause\n    return retryOnce()\n  }\n  throw e\n}","preventionTips":["Always read the console.log line — the original error is printed before the generic rethrow","Keep JWTs fresh (refresh before status queries) on long-lived pages","Verify RLS policies cover every table queried by getContributionState for auth.uid()"],"tags":["supabase","rls","error-wrapping","diagnostics"],"backgroundTag":null,"analyzedSha":"031785bb6dc6b957c624e62bc64c184409c97d7b","analyzedAt":"2026-08-16T06:24:09.996Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}