## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
docs update
## What is the current behavior?
Issues described in this [Slack
thread](https://supabase.slack.com/archives/C02BJ2239GA/p1740408115511769)
## What is the new behavior?
- Full Storage Migration: Transfers all buckets and their contents.
- Bucket Configuration & Metadata Retention: Maintains settings like
public access, file size limits, MIME types, and file metadata.
- Conflict Resolution Options: Skip, merge (overwrite), or rename
buckets in the target project.
- Safety Measures: Requires user confirmation before destructive
actions.
- Efficient Processing: Batches files (10 per batch) and supports nested
directories.
- Progress & Reporting: Real-time updates, detailed migration summaries,
and error tracking for failed files.
---------
Co-authored-by: Illia Basalaiev <illiab@IMB3.local>
## Context
If you've got a queued operation on a table, then switch tables, the
dashboard stalls for a few seconds before finally rendering the selected
table.
This was caused by an infinite loop in a useEffect calling
`reapplyOptimisticUpdates` due to `dataUpdatedAt` being in the
dependency array (which comes from react query)
Removing `dataUpdatedAt` would resolve the issue, but then it won't
solve the following comment in the code:
`// This ensures pending changes remain visible when switching tabs or
after data refresh`
## Changes involved
Opting to refactor the logic for rendering data in the Grid instead
- Avoid manipulating the data directly from the query client
- Manual changes to the query client are hard to track when debugging
- Ideally the data in the query client are exactly what is coming from
the API
- Instead just compute the row data if there's operations applied, and
render that in the grid
```
const baseRows = data?.rows ?? EMPTY_ARR
const rows = formatGridDataWithOperationValues({ operations, rows:
baseRows })
```
- Simplifies operations logic + data in react query remains as the
source of truth
- This also improves perceived performance, as previously we'd need to
invalidate the query client if we're removing any operation.
- A lot more apparent with the undo operation introduced
[here](https://github.com/supabase/supabase/pull/43957)
- Whereas now, we'll just revert back to whatever's in the query client
(and still do the invalidation behind the scenes) so things feel faster
Upgrades `ai` from v5 to v6 and all related packages.
**Package bumps:**
- `ai`: `5.0.52` → `^6.0.116`
- `@ai-sdk/openai`: `2.0.32` → `^3.0.41`
- `@ai-sdk/react`: `2.0.52` → `^3.0.118`
- `@ai-sdk/provider`: `^2.0.0` → `^3.0.8`
- `@ai-sdk/provider-utils`: `^3.0.0` → `^4.0.19`
- `@ai-sdk/amazon-bedrock`: `^3.0.0` → `^4.0.81`
- `@ai-sdk/mcp`: N/A → `^1.0.25`
- `openai`: bumped to `^4.104.0`
- `braintrust`: `3.0.x` → `^3.4.0`
**Breaking change migrations:**
- `generateObject` removed in v6 — migrated 5 API routes to
`generateText` with `Output.object({ schema })`, returning
`result.output`
- `convertToModelMessages` is now async — added `await`
- MCP import path changed: `experimental_createMCPClient` from `ai` →
`createMCPClient` from `@ai-sdk/mcp`
- `openai()` defaults to Responses API — added `store: false` to
provider options for ZDR org compatibility
**Streaming fix:**
Added `Content-Encoding: none` header to `pipeUIMessageStreamToResponse`
calls. Without it, proxy middleware buffers the entire SSE response
before flushing, causing the full reply to appear at once.
**Zero Data Retention fix:**
In recent AI SDK versions, `openai()` default to Responses API instead
of the legacy chat completions API. This produces a 404 from OpenAI with
message `"Items are not persisted for Zero Data Retention organizations.
Remove this item from your input and try again."` The Responses API is
OpenAI's [recommended
endpoint](https://developers.openai.com/api/docs/guides/migrate-to-responses).
This PR adds `store: false` as mentioned in
https://github.com/vercel/ai/issues/10060 to avoid incompatible
persistence attempts.
**References:**
- https://ai-sdk.dev/docs/migration-guides/migration-guide-6-0
-
https://ai-sdk.dev/docs/troubleshooting/streaming-not-working-when-proxied
- https://github.com/vercel/ai/issues/10060
Closes AI-514
Related AI-509
## Context
Shifting more dashboard queries into pg-meta so that we centralize all
manually written queries in one place
Having them in packages/pg-meta also allows us to write tests for them
## To test
Just needs a smoke test on
- Table Editor
- Fetching entities
- Viewing definition
- SQL Editor
- View ongoing queries
- Abort queries
- Integrations
- Queues
- Database
- Migrations
-Triggers (Updating)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Refactor
## What is the current behavior?
The `/incident-banner` endpoint is implemented using the Pages Router.
## What is the new behavior?
The `/incident-banner` endpoint is moved to the App Router, enabling
caching of the upstream fetch. This does not turn on the querying from
the frontend yet, making that a separate PR so we can revert easily if
needed.
## Additional context
Fixes#42089
Supersedes #43352 and
https://github.com/supabase/postgres-meta/pull/1049
## Problem
When creating a table in the Dashboard, if a column-specific error
occurs (e.g., invalid enum value or broken foreign key), the Dashboard
displays an error toast, but the side panel remains open. In the
background, the table is actually created (partially), leading to a
_42P07: relation already exists_ error if the user tries to click _Save_
again.
## Solution
We actually had nested transactions which is not supported by Postgres.
- [x] Allow generating SQL without transactions from `@supabase/pg-meta`
- [x] Fix the table creation
- [x] Fix some accessibility issues
- [x] Add tests
## How to test
1. Click _New table_ in the Table editor
2. Add a column with an _int8_ type and set its default value to
`bazinga`
3. Click _Save_
You should see an error.
4. Fix the default value by setting it to `10`
5. Click _Save_
Results:
- You should see a success message about the table creation
- The table should have the column with the correct default value
<img width="1543" height="981" alt="image"
src="https://github.com/user-attachments/assets/8e6c37c5-15c7-4bc4-be87-477e36a62a65"
/>
Switches from two to one column layout for details page and removes an
inconsistent background colour in header. Moves critical detail
information from page into header (url and deploy dates/counts)
## What kind of change does this PR introduce?
- Bug fix that resolves DEPR-396
- Additional improvements to blog post image handling
## What is the current behavior?
Blog post Open Graph metadata often prefers `imgThumb` over `imgSocial`,
so social previews on X, iMessage, and similar surfaces can render the
on-site thumbnail instead of the intended social image.
The image selection and path-normalization rules are also duplicated
across blog surfaces, which makes the precedence rules easy to drift.
## What is the new behavior?
- Centralizes blog image handling in `apps/www/lib/blog-images.ts`
- Uses `imgSocial` first, then `imgThumb`, for blog OG/Twitter metadata
- Uses `imgThumb` first, then `imgSocial`, then the placeholder, for
blog thumbnails and post hero images
- Normalizes relative blog image paths into absolute URLs for metadata
- Adds warning-only validation during content reads/builds for partial
or malformed `imgSocial` / `imgThumb` config
- Updates a few recent blog posts so `imgThumb` is a thumbnail-only
asset instead of duplicating the social image
## Additional context
- Replaces #42319 with the additional above fixes
- Added unit coverage for the shared image helper
---------
Co-authored-by: Alan Daniel <stylesshjs@gmail.com>
## What kind of change does this PR introduce?
Bug fix. Resolves FE-2802. Fixes#43882.
## What is the current behavior?
Second-level foreign key side panels in Table Editor can be dismissed
while dirty without a discard confirmation. That makes accidental
dismissal easy and is inconsistent with the shared dirty-form dismissal
pattern from FE-2802.
## What is the new behavior?
- Adds `DiscardChangesConfirmationDialog` handling to
`ForeignKeySelector`
- Guards all selector close paths behind a local dirty-state check
- Normalizes foreign key state so derived type metadata does not create
false dirty prompts
- Clarifies in `modality.mdx` that route-driven/page-unload flows should
use a navigation guard rather than the dialog/sheet close guard
| Dirty State | Dialog |
| --- | --- |
| <img width="1502" height="899" alt="test Table Editor AWS Healthy
Toolshed Supabase-D1EA9D5F-46EB-4DB5-830D-7CEF36A55B7E"
src="https://github.com/user-attachments/assets/3d866850-d062-4fb7-9949-2fd713e6088f"
/> | <img width="1502" height="899" alt="test Table Editor AWS Healthy
Toolshed Supabase"
src="https://github.com/user-attachments/assets/1396361d-1d44-4206-862f-3379ea22be30"
/> |
## Additional context
Includes a focused unit test for foreign key dirty-state normalization.
## What kind of change does this PR introduce?
Bug fix.
## What is the current behavior?
Webhook endpoint validation is inconsistent across Studio forms. The
webhook sheet accepts incomplete hostnames like `https://webhook`, event
type validation is not surfaced clearly, and HTTP endpoint validation
differs between webhooks, log drains, cron jobs, and database hooks.
## What is the new behavior?
- Tightens webhook endpoint URL validation and rejects incomplete
hostnames while still allowing localhost and IP-based endpoints.
- Surfaces the Event types validation through the standard form error
styling and highlights the existing accordion item border when invalid.
- **Extracts a shared HTTP endpoint URL validator and reuses it in
webhooks, log drains, cron jobs, and database hooks.**
- Adds focused regression tests for the webhook sheet and the
shared/consumer validation paths.
| After |
| --- |
| <img width="1728" height="997" alt="Webhooks Settings AWS Healthy
Toolshed Supabase-CB0D999C-D0BF-47AA-A10F-342A2E328DF9"
src="https://github.com/user-attachments/assets/bcbe4876-f9a7-497a-b288-460087a65546"
/> |
## To test
Form behaviour (in particular URL validation) on:
- Webhook endpoint
- Log drains
- Cron jobs
- Database hooks
## Problem
PR #43704 added the `tableEditorApiAccessToggle` flag to revoke default
privileges on project creation, but there's no PostHog instrumentation
to measure the rollout or understand how users respond to the new
behavior.
## Changes
**1. Flag state on project creation**
(`project_creation_simple_version_submitted`)
Adds `tableEditorApiAccessToggleEnabled` property — reads the raw
PostHog flag via `usePHFlag` rather than going through
`useDataApiGrantTogglesEnabled`, which coerces `undefined` (flag still
loading) to `false` and would silently poison the data. When the flag
hasn't loaded, the property is omitted from the event entirely.
**2. Per-table toggle tracking** (`table_api_access_toggle_clicked`)
New event that fires when a user flips the Data API access switch in the
table editor side panel (new tables only — existing tables link out to
settings). Tracks `newState: 'enabled' | 'disabled'` and `schemaName` so
we can distinguish public-schema toggles from custom schemas.
Together these let us answer: what % of projects have the new defaults,
and how do those users respond (do they opt tables back in, and in which
schemas)?
Part of the Secure by Default initiative (#43704)
## Context
Noticed while working on #43913 that `copilot-instructions.md` is
currently at ~4,600 characters. Per [GitHub's docs on Copilot code
review](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/request-a-code-review/use-code-review):
> Copilot code review only reads the first 4,000 characters of any
custom instruction file. Any instructions beyond this limit will not
affect the reviews generated by Copilot code review.
This means the testing section at the bottom of our current file isn't
being read during reviews.
## Proposal
Split the single file into path-specific instruction files under
`.github/instructions/`, following [GitHub's recommended pattern for
repository custom
instructions](https://docs.github.com/en/copilot/how-tos/configure-custom-instructions/add-repository-instructions):
> These are specified in one or more `NAME.instructions.md` files within
or below the `.github/instructions` directory.
> If the path you specify matches a file that Copilot is working on, and
a repository-wide custom instructions file also exists, then the
instructions from both files are used.
This gives us separate files that each stay under the 4K limit and get
combined automatically by Copilot during reviews:
| File | Size | Scope |
|------|------|-------|
| `copilot-instructions.md` | 929 chars | General repo context +
pointers |
| `instructions/studio-telemetry.instructions.md` | 3,570 chars |
Telemetry rules for `apps/studio/**` |
| `instructions/studio-testing.instructions.md` | 1,228 chars | Testing
rules for `apps/studio/**` |
Note: Copilot reads instructions from the **base branch** of a PR, not
the feature branch — so these won't take effect until merged to master.
### New telemetry guidance
The telemetry file adds guidance we've been missing — specifically
around feature-flagged rollouts:
- Flag PRs that use `usePHFlag`/`useFlag` to gate behavior but don't
capture the flag state in telemetry
- Flag rollouts that track flag state but not user response to the new
behavior
- Documents the raw flag pattern (read via `usePHFlag`, not coerced
wrapper hooks) to avoid the `undefined`→`false` data quality bug we hit
in #43913
### What didn't change
All existing telemetry and testing rules are preserved — nothing was
removed, just reorganized. The telemetry rules still reference
`.claude/skills/telemetry-standards/SKILL.md` as the authoritative
source.
## References
- [Adding repository custom instructions for GitHub
Copilot](https://docs.github.com/en/copilot/how-tos/configure-custom-instructions/add-repository-instructions)
— file structure, path-specific instructions, frontmatter format
- [Using Copilot code
review](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/request-a-code-review/use-code-review)
— 4K character limit, base branch behavior
## Open questions
Would love the team's input on:
- Does the file split make sense, or would you prefer keeping everything
in one file (and trimming to fit)?
- Are there other topics that should get their own instruction file?
- Any concerns with the new feature flag telemetry guidance?
## Context
Similar to how we added a banner for the new table filter bar - mainly
to improve visibility for this feature preview as we'd like some
feedback from usage
<img width="313" height="314" alt="image"
src="https://github.com/user-attachments/assets/4cea6383-483a-42cf-b4a5-bb8c3918c00d"
/>
## Other changes
- Also adding some typing to the `addBanner` and `dismissBanner`
- Removed banner for table editor filter bar
## What kind of change does this PR introduce?
Chore that resolves DEPR-399.
## What is the current behavior?
The cron jobs table in Studio uses a fixed-width `Name` column, which
can truncate long job titles and make them hard to read on
`/project/:ref/integrations/cron/jobs`.
## What is the new behavior?
The cron jobs table now allows resizing the informational columns,
including `Name`, `Schedule`, `Last run`, `Next run`, and `Command`,
while keeping the `Active` and `Actions` columns fixed-width.
This also gives the `Name` column a sensible minimum width so it can be
resized without collapsing.
## Additional context
Adds a small regression test around the cron jobs column configuration
to verify that:
- informational columns are resizable
- utility columns remain fixed
- the `Name` column has a non-zero minimum width
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
- refactor navigation utils to pass in is_platform
- write unit tests for configuration returns
- default is always passed from constant IS_PLATFORM
## Context
Adds a source filter for the query performance advisor so you can filter
out queries from the dashboard, or not from the dashboard
<img width="309" height="217" alt="image"
src="https://github.com/user-attachments/assets/c1fab9af-e57e-482f-afdb-d77a6600edb3"
/>
For transparency how this works:
- Queries fired via the dashboard through the /query endpoint get
enriched with metadata from the API to include a comment like `--
source: dashboard`
- That's mainly how this filter works atm, to check if this comment
exists if the source "Dashboard" is selected, and the inverse if the
source "Non dashboard" is selected
## Summary
Adds `.github/copilot-instructions.md` to configure GitHub Copilot Code
Review with telemetry and testing guidelines. Replaces CodeRabbit as our
automated PR reviewer. Copilot will now advisory-comment when PRs touch
growth-oriented components (onboarding, upgrade CTAs, A/B experiments)
without telemetry tracking, or when Studio changes lack appropriate test
coverage.
## Changes
- Add `.github/copilot-instructions.md` with:
- Telemetry review rules: event naming (`[object]_[verb]`), property
conventions, `useTrack` enforcement, missing tracking suggestions for
growth surfaces
- Testing review rules: logic extraction to `.utils.ts`, test type
decision tree, file naming conventions
- Repo context and references to full Claude skill docs
## Testing
- [x] Verified `.github/copilot-instructions.md` is the correct path for
Copilot Code Review
- [x] Rules are condensed from existing Claude skills
(`telemetry-standards`, `studio-testing`) — verified alignment
## Linear
- fixes GROWTH-698
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This PR updates @supabase/*-js libraries to version 2.100.0-canary.0.
**Source**: manual
**Changes**:
- Updated @supabase/supabase-js to 2.100.0-canary.0
- Updated @supabase/auth-js to 2.100.0-canary.0
- Updated @supabase/realtime-js to 2.100.0-canary.0
- Updated @supabase/postgest-js to 2.100.0-canary.0
- Refreshed pnpm-lock.yaml
This PR was created automatically.
Co-authored-by: mandarini <6603745+mandarini@users.noreply.github.com>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Refactor
## What is the current behavior?
`/incident-status` is handled via Pages Router.
## What is the new behavior?
`/incident-status` is handled via App Router, enabling use of Vercel
Data Cache to cache the upstream fetch.
## Additional context
Adding the first App Router route handler triggered `next typegen` (run
as `pretypecheck`) to generate `.next/dev/types/validator.ts`, which
imports all route files and expanded the type-checked graph. This
surfaced pre-existing `null`-safety errors in:
- `components/grid/SupabaseGrid.utils.ts` — `useSearchParams()` result
- `components/layouts/ProjectLayout/UpgradingState/index.tsx` —
`useSearchParams()` result
- `pages/project/[ref]/sql/quickstarts.tsx` — `useParams()` result
- `pages/project/[ref]/sql/templates.tsx` — `useParams()` result
These are fixed with optional chaining. The `tsconfig.json` change
(adding `.next/dev/types/**/*.ts` to `include`) is auto-generated by
Next.js and committed as correct behavior.
This PR:
* Adds an upgrade flow to the stripe sync engine, allowing users to
upgrade to the latest version when it becomes available.
* When a new version of sync engine becomes available, users will see an
upgrade button instead of install button.
* Bumps `supabase-management-js` to version 2.0.2 and
`stripe-experiment-sync` to version 1.0.27.
* Uses `parseSchemaComment` and related logic from the
`stripe-experiment-sync` package in order to avoid writing duplicate
code in supabase ui.
* Allows installation/uninstallation to timeout after 5 minutes to avoid
these operations from getting stuck in case an error occurs in their
processing. This allows users to retry the operation, as opposed to the
older behaviour where the users always see a spinner on the
install/uninstall button and couldn't do anything.
* Remove the SSL enforcement admonition as it is no longer required.
Sync engine can now be installed with or without SSL enforcement
enabled.
---------
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
## Context
Resolves FE-2794
Just addressing some friction points i ran into when setting up MFA for
my account under account preferences
## Changes involved
- Hitting enter at each step of setting up MFA will submit and proceed
(Previously didn't, had to click buttons)
- When logging in with MFA, automatically submit after entering 6 digits
- Refactored to use react hook form for `AddNewFactorModal` in
`FirstStep` and `SecondStep` + simplified the logic a little
When the `tableEditorApiAccessToggle` feature flag is enabled, project
creation now appends SQL to revoke default privileges for `anon`,
`authenticated`, and `service_role` on the `public` schema. This runs
after the base image init script's default grants. This is temporary
while we're still using a feature flag. Eventually it'll be moved into
the base image.
Applies to both the main project creation flow and the Vercel deploy
button flow.
Part of the "Secure by Default" initiative – new projects created under
this flag won't automatically expose tables/functions/sequences to the
Data API via default privileges. Users can still opt in at a table
level.
## Notes
Reusing the existing `useDataApiGrantTogglesEnabled()` flag here rather
than creating a new one – it's the same feature surface area and avoids
unnecessary flag proliferation.
## To test
1. **With flag enabled:**
- Enable the `tableEditorApiAccessToggle` flag in PostHog for your user
- Create a new project via the dashboard
- Create a new table
- Confirm in `/project/_/integrations/data_api/settings` that the new
table is not exposed by default
2. **With flag disabled:**
- Disable the flag (or use a different user without it)
- Create a new project
- Verify default privileges are intact and tables are accessible via the
Data API as usual
3. **With RLS event trigger enabled too:**
- Enable both the feature flag and the "enable RLS event trigger"
checkbox during project creation
- Verify both SQL statements run correctly on the new project
---------
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES/NO
## What kind of change does this PR introduce?
Docs update
## What is the current behavior?
Many troubleshooting guides referencing Postgres functions were placed
in the edge function category
## What is the new behavior?
Removed the "function" topic filter for guides that are unrelated to
edge functions
## What kind of change does this PR introduce?
Feature / UX update.
## What is the current behavior?
Platform webhook deliveries cannot be retried from the deliveries table
or the delivery details sheet.
## What is the new behavior?
- Adds a retry action to individual platform webhook deliveries in the
endpoint deliveries table
- Adds a retry action to the shared delivery details sheet footer
- Limits retry to non-success deliveries
- Applies the table action hit area guidance from the design system
Successful deliveries should also not expose retry in this mock flow.
## Additional context
- Addresses DEPR-340.
- In the current mock implementation, queueing updates the existing
delivery in place: it sets the status to `pending`, clears
`responseCode`, and refreshes `attemptAt` to the current timestamp.
- The mock does not create a separate queued job or append a new
delivery record yet; the same delivery is resurfaced at the top of the
list because deliveries are sorted by latest attempt time.
### FAQ (`type: 'faq'`)
Accordion-style FAQ with expand/collapse. Each item has a `question` and
`answer`. Click to toggle — only one open at a time.
<img width="1309" height="610" alt="Screenshot 2026-03-13 at 17 31 31"
src="https://github.com/user-attachments/assets/289c8a12-3835-4f64-bbe6-fb7095df4e7c"
/>
### Code Block (`type: 'code-block'`)
Syntax-highlighted code display using shiki with custom Supabase
dark/light themes. Supports:
- **Single file** — `code` + optional `filename` + `language`
- **Multi-file** — `files: [{ filename, code, language }]` with
clickable tabs
- Line numbers via CSS counters
- All highlighting runs at build time (server component), only tab
switching is client-side
<img width="1283" height="415" alt="Screenshot 2026-03-13 at 17 32 07"
src="https://github.com/user-attachments/assets/9cc9a215-d5c9-47c9-8e21-c1dd3beca4ba"
/>
### Steps (`type: 'steps'`)
Numbered step-by-step guide with a vertical timeline connector. Each
item has `title` and either a plain `description` string or a `content`
slot accepting any React node (e.g. images, code blocks).
<img width="1119" height="810" alt="Screenshot 2026-03-13 at 17 32 20"
src="https://github.com/user-attachments/assets/cb67aaab-9ed4-42e2-bf1c-8d836024e469"
/>
### Quote (`type: 'quote'`)
Centered testimonial block with `quote`, `author`, optional `role`, and
optional `avatar` image.
<img width="1095" height="238" alt="Screenshot 2026-03-13 at 17 32 37"
src="https://github.com/user-attachments/assets/356a39ca-9f65-4414-bf77-6060993594a4"
/>