---
title: update_dashboard
description: Rename a dashboard or edit its metadata without republishing it. Parameters, the rename pipeline, errors and scope rules.
updated: 2026-09-22
tools: [update_dashboard]
---

Changes a dashboard's metadata, renames it, or both, without republishing it.
A rename leaves the old URL working as a 301 redirect to the new canonical
one. To replace the body, use
[`publish_dashboard`](/reference/mcp-tools/publish-dashboard) instead.

When you combine `new_slug` with metadata fields, both apply atomically.

Behaviour hints for clients: not read-only, idempotent, not open-world.

## Parameters

| Parameter | Type | Required | Notes |
|---|---|---|---|
| `slug` | string | yes | The dashboard's current canonical slug. |
| `new_slug` | string | no | Rename target. Must differ from `slug` and not collide with another slug or alias of yours. |
| `name` | string | no | Display name. Omit to preserve. Empty string is rejected. |
| `tags` | array | no | Omit to preserve, `[]` to clear. |
| `chart` | string | no | Omit to preserve. Empty string is rejected. |
| `workspace` | string | no | Workspace slug. |

At least one of `new_slug`, `name`, `tags` or `chart` must be provided.

:::note{title="The display name follows the URL by default"}
Passing `new_slug` without `name` auto-sets the name to the title-cased form of
the new slug, so `quarterly-revenue` becomes `Quarterly Revenue`. Pass `name`
explicitly to keep a custom label through a rename.
:::

## Returns

A rename:

```text
Updated workspace dashboard.
Renamed: marketing-dashboard -> quarterly-revenue
Name: Quarterly Revenue
Chart: bar
Tags: marketing, q2
URL: https://acme.dashies.ai/quarterly-revenue
```

A metadata-only edit reports the current state, and carries `Slug` where the rename carries
`Renamed`:

```text
Updated workspace dashboard.
Slug: quarterly-revenue
Name: Quarterly Revenue
URL: https://acme.dashies.ai/quarterly-revenue
```

**`Chart` and `Tags` belong to the RENAME shape**, where they appear only when set. The
metadata shape is exactly the block above it and never carries either, whatever the dashboard
has. The trailing `URL` line is appended by the tool rather than built by the update itself, so
it is the last line of both.

**There is no OLD-URL line.** A rename leaves the previous slug as an alias that 301s, which
[URLs, slugs and reserved names](/reference/urls-and-slugs) covers, but the receipt does not
restate it.

## Errors

Beyond the shared [path and metadata rules](/reference/mcp-tools/conventions#dashboard-metadata):

| Condition | Text |
|---|---|
| `new_slug` not a string | `new_slug must be a string` |
| `new_slug` fails slug validation | `new_slug invalid: <slug error>` |
| `new_slug` equals `slug` | `new_slug must differ from slug` |
| Nothing to change | `at least one of new_slug, name, tags, chart must be provided` |
| `visibility` passed at all | `visibility is no longer accepted: public dashboards have been removed, so every dashboard is visible to its owner or, for a workspace dashboard, to that workspace's members. Omit the argument.` |
| The slug names no dashboard, on a metadata-only edit | `dashboard not found for slug "<slug>"` |

**A metadata-only edit of a slug that does not exist is a not-found rather than a silent
create.** A RENAME of a missing slug is refused by the database in the same words, and that
sentence is one of the permanent patterns, so it arrives inside the `rename rejected: <msg>`
form that `Rename failures tell you whether to retry` covers.

### Rename failures tell you whether to retry

A rename is three steps: reserve the new slug, copy the bytes, then promote
atomically. Each failure names where it stopped and whether retrying is safe.

| Text | What happened, and what to do |
|---|---|
| `rename rejected: <msg>` | A permanent refusal such as a collision or a validation failure. Do not retry with the same arguments. |
| `rename reserve failed (no DB or R2 changes yet - safe to retry): <msg>` | Nothing was touched. Retry. |
| `r2 copy failed (new_slug "<new>" remains reserved by this dashboard; retry to complete the rename, or pick a different new_slug): <err>` | The name is claimed by this dashboard. Retry to finish, or choose another target to abandon it. |
| `db rename failed (reservation + R2 already in place; old URL still works - safe to retry): <msg>` | The old URL is still serving. Retry. |
| `metadata update failed: <msg>` | The metadata-only path failed. Nothing renamed. |

Retrying with the same arguments is safe by design: the reservation is
idempotent, and a call that succeeded but whose response was lost is detected and
returned as success on retry.

:::warning{title="A rename invalidates a list cursor"}
This call bumps the row's `updated_at`, and
[`list_dashboards`](/reference/mcp-tools/list-dashboards) paginates on that
column. If you are walking pages and rename mid-walk, discard the cursor and
restart from a fresh first page, or you will skip the row you just changed.
:::

## Scope

The renamed URL is `<workspace>.dashies.ai/<new_slug>` and
the old one 301-redirects.

## Check it worked

Load the old URL. It should 301 to the new one rather than 404. Then run
[`list_dashboards`](/reference/mcp-tools/list-dashboards) and confirm the entry
shows the new slug and the name you expected, since a rename without an explicit
`name` rewrites the display name too.
