Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/docs/content/guides/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ subtitle: 'Developing locally using the Supabase CLI.'
sidebar_label: 'Overview'
---

You can use the Supabase CLI to run the entire Supabase stack locally on your machine, by running `supabase init` and then `supabase start`. To install the CLI, see the [installation guide](/docs/guides/cli/getting-started#installing-the-supabase-cli).
You can use the Supabase CLI to run the entire Supabase stack locally on your machine, by running `supabase init` and then `supabase start`. To install the CLI, read [the installation guide](/docs/guides/cli/getting-started#installing-the-supabase-cli).

The Supabase CLI provides tools to develop your project locally, deploy to the Supabase Platform, handle database migrations, and generate types directly from your database schema.

Expand Down
69 changes: 6 additions & 63 deletions apps/docs/content/guides/local-development/cli/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -72,28 +72,12 @@ The Supabase CLI requires **Node.js 20 or later** when run via `npx` or `npm`. O

</Admonition>

<Admonition type="note">

Installing the Supabase CLI globally using `npm install -g supabase` is **not supported**.

For global usage, install the CLI via Homebrew, Scoop, or the standalone binary.

Alternatively, you can run the CLI using `npx supabase` or install it locally as a dev dependency.

</Admonition>

You can also install the CLI as dev dependency via [npm](https://www.npmjs.com/package/supabase):

```sh
npm install supabase --save-dev
```

<Admonition type="note">

Global installation using `npm install -g supabase` is not supported. For global CLI usage, install via [Homebrew](/docs/guides/local-development/cli/getting-started?queryGroups=platform&platform=macos), [Scoop](/docs/guides/local-development/cli/getting-started?queryGroups=platform&platform=windows), or the [standalone binary](/docs/guides/local-development/cli/getting-started?queryGroups=platform&platform=linux).

</Admonition>

</TabPanel>
</Tabs>

Expand Down Expand Up @@ -157,7 +141,7 @@ npx supabase@beta --help

## Updating the Supabase CLI

When a new [version](https://github.com/supabase/cli/releases) is released, you can update the CLI using the same methods.
When a new [version](https://github.com/supabase/cli/releases) is released, you can update the CLI using the same channels.

<Tabs
scrollable
Expand Down Expand Up @@ -248,46 +232,7 @@ supabase stop --no-backup

## Running Supabase locally

The Supabase CLI uses Docker containers to manage the local development stack. Follow the official guide to install and configure [Docker Desktop](https://docs.docker.com/desktop):

<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="macos"
queryGroup="platform"
>
<TabPanel id="macos" label="macOS">

<Image
alt="Docker settings on Mac: Select Integrated, Virtualization Framework, and osxfs"
src={{
dark: '/docs/img/guides/cli/docker-mac.png',
light: '/docs/img/guides/cli/docker-mac-light.png',
}}

width={2880}
height={1800}
/>

</TabPanel>
<TabPanel id="windows" label="Windows">

<Image
alt="Docker settings on Windows: Select Integrated, Expose Daemon, WSL2, and Add to /etc/hosts file."
src={{
dark: '/docs/img/guides/cli/docker-win.png',
light: '/docs/img/guides/cli/docker-win-light.png',
}}

width={2560}
height={1520}
/>

</TabPanel>
</Tabs>

<Admonition type="note">
The Supabase CLI uses Docker containers to manage the local development stack. Follow the official guide to install and configure [Docker Desktop](https://docs.docker.com/desktop) on your machine.

Alternately, you can use a different container tool that offers Docker compatible APIs.

Expand All @@ -296,27 +241,25 @@ Alternately, you can use a different container tool that offers Docker compatibl
- [OrbStack](https://orbstack.dev/) (macOS)
- [colima](https://github.com/abiosoft/colima) (macOS)

</Admonition>

Inside the folder where you want to create your project, run:

```bash
supabase init
```

This will create a new `supabase` folder. It's safe to commit this folder to your version control system.
This creates a new `supabase` folder. It's safe to commit this folder to version control.

Now, to start the Supabase stack, run:

```bash
supabase start
```

This takes time on your first run because the CLI needs to download the Docker images to your local machine. The CLI includes the entire Supabase toolset, and a few additional images that are useful for local development (like a local SMTP server and a database diff tool).
This takes time on your first run because the CLI needs to download the Docker images to your local machine. The CLI includes the entire Supabase stack, and a few additional images useful for local development (like a local SMTP server and a database diff tool).

## Access your project's services

Once all of the Supabase services are running, you'll see output containing your local Supabase credentials. It should look like this, with urls and keys that you'll use in your local project:
Once all the Supabase services are running, you'll see output containing your local Supabase credentials. It should look like the below, with urls and keys that you use in your local project:

```
Started supabase local development setup.
Expand Down Expand Up @@ -427,7 +370,7 @@ For advanced logs analysis using the Logs Explorer, it is advised to use the Big

</Admonition>

All logs will be stored in the local database under the `_analytics` schema.
All logs are stored in the local database under the `_analytics` schema.

</TabPanel>
</Tabs>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,88 @@ keywords = [ "users" ]
database_id = "5d1c44ed-b2f6-4509-9312-1eeb8838e701"

[[errors]]
http_status_code = 500
code = "unexpected_failure"
message = "Database error saving new user"

[[errors]]
http_status_code = 500
code = "unexpected_failure"
message = "Database error creating new user"
---

You generally get this error when trying to invite a new user from the dashboard or when trying to insert a user into a table using the table editor in the Supabase dashboard.
You generally get this error when trying to invite a new user from the dashboard or when trying to insert a user into a table using the table editor in the Supabase dashboard. You may also see this error in logs in connection to failed signups.

This error is normally associated with a side effect of a database transaction.

**Common causes of this error:**

- You have a trigger/trigger function setup on the `auth.users` table
- You have a trigger/trigger function setup on the `auth.users` table that has an error
- You have added a constraint on the `auth.users` table which isn't being met
- You are using Prisma and it has broken all the permissions on the `auth.users` table

**Debugging this error:**
## Debugging this error:

**Step 1: Check the Auth logs**

Start in the [Auth logs explorer](/dashboard/project/_/logs/auth-logs) in your project dashboard. The logs surface the specific error message and give you the most direct signal about what went wrong.

**Step 2: Check the Postgres logs**

If the Auth logs point to a database-level issue, open the [Postgres logs explorer](/dashboard/project/_/logs/postgres-logs) to look for corresponding errors.

---

## Common errors

### NULL value in auth schema column

**Example Auth log error:**

```
500: Database error querying schema
error finding user: sql: Scan error on column index 8, name "confirmation_token": converting NULL to string is unsupported
```

**Cause:**

The `auth` schema is managed by Supabase and expects specific column formats. This error typically happens when users are inserted directly via SQL or using an AI tool that uses a direct SQL `INSERT`, rather than through the [Auth API](/docs/reference/javascript/auth-api). A direct insert can leave required columns as `NULL` when the Auth service expects an empty string.

**Fix:**

Run the following in the [SQL editor](/dashboard/project/_/sql), replacing `confirmation_token` with whichever column appears in your error message:

```sql
update auth.users
set confirmation_token = ''
where confirmation_token is null;
```

This sets all `NULL` values in that column to an empty string, which is what the Auth service expects.

---

### Relation does not exist

**Example Auth log error:**

```
failed to close prepared statement: ERROR: current transaction is aborted, commands ignored until end of transaction block (SQLSTATE 25P02): ERROR: relation "profiles" does not exist (SQLSTATE 42P01)
```

**Example Postgres log error:**

```
event_message: "relation "profiles" does not exist"
context: "PL/pgSQL function public.handle_new_user() line 3 at SQL statement"
```

**Cause:**

A trigger on `auth.users` is calling a function (in this case `handle_new_user`) that tries to insert into a table that does not exist. This is common when a `profiles` table is referenced in a trigger function but was never created, or was accidentally dropped.

**Fix:**

- You can use the [Auth logs explorer](https://app.supabase.com/project/_/logs/auth-logs) to find the issue with more information
- You can use the [Postgres logs explorer](https://app.supabase.com/project/_/logs/postgres-logs)
1. Check whether the missing table should exist in your `public` schema. If it should, create the table for the trigger to succeed and the error should resolve.

https://user-images.githubusercontent.com/79497/225517698-b6e3ccaf-cd70-4acd-8124-ffbcee310d63.mp4
2. If the table is not needed, review the function definition and update or remove the reference. You can view and edit your database functions from the [Database Functions](/dashboard/project/_/database/functions) page in the dashboard.
46 changes: 46 additions & 0 deletions apps/docs/features/docs/MdxAnchor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { ExternalLink as ExternalLinkIcon } from 'lucide-react'
import { type ComponentPropsWithoutRef } from 'react'
import { cn } from 'ui'

const isExternalHref = (href?: string) => {
if (!href || !/^https?:\/\//i.test(href)) return false
try {
return !/(^|\.)supabase\.com$/i.test(new URL(href).hostname)
} catch {
return false
}
}

// Walk the tree and concatenate text so the aria-label matches the visible link
const flattenChildrenToText = (node: unknown): string => {
if (node == null || typeof node === 'boolean') return ''
if (typeof node === 'string' || typeof node === 'number') return String(node)
if (Array.isArray(node)) return node.map(flattenChildrenToText).join('')
if (typeof node === 'object' && node !== null && 'props' in node) {
const props = (node as { props?: { children?: unknown } }).props
return flattenChildrenToText(props?.children)
}
return ''
}

export function MdxAnchor({ href, children, ...rest }: ComponentPropsWithoutRef<'a'>) {
if (!isExternalHref(href)) {
return (
<a href={href} {...rest}>
{children}
</a>
)
}
const label = flattenChildrenToText(children).trim()
return (
<a href={href} aria-label={label ? `External Source: ${label}` : undefined} {...rest}>
{children}
<ExternalLinkIcon
size={14}
strokeWidth={1.5}
aria-hidden="true"
className="inline-block align-[-1px] ml-0.5 text-lighter"
/>
</a>
)
}
2 changes: 2 additions & 0 deletions apps/docs/features/docs/MdxBase.shared.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { SharedData } from '~/components/SharedData'
import StepHikeCompact from '~/components/StepHikeCompact'
import { CodeSampleDummy, CodeSampleWrapper } from '~/features/directives/CodeSample.client'
import { NamedCodeBlock } from '~/features/directives/CodeTabs.components'
import { MdxAnchor } from '~/features/docs/MdxAnchor'
import { Accordion, AccordionItem } from '~/features/ui/Accordion'
import { CodeBlock } from '~/features/ui/CodeBlock/CodeBlock'
import InfoTooltip from '~/features/ui/InfoTooltip'
Expand Down Expand Up @@ -100,6 +101,7 @@ const components = {
Tabs,
TabPanel,
InfoTooltip,
a: MdxAnchor,
h2: (props: any) => (
<Heading tag="h2" {...props}>
{props.children}
Expand Down
Binary file not shown.
Binary file removed apps/docs/public/img/guides/cli/docker-mac.png
Binary file not shown.
Binary file not shown.
Binary file removed apps/docs/public/img/guides/cli/docker-win.png
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ export const DestinationPanelFormSchema = z.object({
ducklakeS3UrlStyle: z.enum(['path', 'vhost']).optional(),
ducklakeS3UseSsl: z.boolean().optional(),
ducklakeMetadataSchema: z.string().optional(),
// Snowflake fields
snowflakeAccountId: z.string().optional(),
snowflakeUser: z.string().optional(),
snowflakePrivateKey: z.string().optional(),
snowflakePrivateKeyPassphrase: z.string().optional(),
snowflakeDatabase: z.string().optional(),
snowflakeSchema: z.string().optional(),
snowflakeRole: z.string().optional(),
})

export type DestinationPanelSchemaType = z.infer<typeof DestinationPanelFormSchema>
Loading
Loading