chatboxai/chatbox · warning · VibedropSlugNotOwnedError

slug no longer owned

Error message

slug no longer owned

What it means

Thrown as VibedropSlugNotOwnedError when the VibeDrop inline-publish endpoint returns 404 with error.code === 'slug_not_owned'. It signals that the requested slug was previously published but the current account/key no longer owns it (e.g. transferred, deleted, or owned by another account).

Source

Thrown at src/renderer/packages/vibedrop.ts:104

}

export async function publishToVibedrop(params: PublishToVibedropParams): Promise<VibedropSite> {
  const { html, vdKey, title, visibility, slug } = params
  if (!html?.trim()) {
    throw new Error('HTML content is empty, nothing to publish.')
  }

  const body: Record<string, unknown> = { html, visibility }
  if (title) body.title = title
  if (slug) body.slug = slug

  const { status, json } = await postJson(`${VIBEDROP_API_ORIGIN}/v1/sites/inline`, body, vdKey)

  if (status === 401 || status === 403) {
    throw new VibedropAuthError(json?.error?.message || 'VibeDrop authorization failed')
  }
  if (status === 404 && json?.error?.code === 'slug_not_owned') {
    throw new VibedropSlugNotOwnedError('slug no longer owned')
  }
  if (status >= 400 || !json?.site?.url) {
    throw new Error(json?.error?.message || `Failed to publish to VibeDrop (status ${status})`)
  }

  return { slug: json.site.slug, url: json.site.url, visibility: json.site.visibility }
}

// ===== client-side caches (settings-persisted) =====

// Decodes the email claim from the current account's JWT access token. Used to
// bind the cached publish key to an account so it is never reused across
// accounts (e.g. after switching login without an explicit logout).
function currentAccountEmail(): string | null {
  const token = authInfoStore.getState().accessToken
  if (!token) return null
  try {
    const payload = token.split('.')[1]

View on GitHub (pinned to 81571269ad)

Solutions

  1. Publish without specifying the slug to let VibeDrop assign a new one.
  2. Choose a different, unused slug.
  3. If ownership is expected, re-verify the account/vdKey matches the one that originally created the slug.
Defensive patterns

Strategy: try-catch

Validate before calling

// Cannot pre-validate ownership without a server lookup.
// Mitigation: avoid passing a slug, or let the user pick a fresh slug.

Type guard

function isVibedropSlugNotOwnedError(e: unknown): e is VibedropSlugNotOwnedError {
  return e instanceof VibedropSlugNotOwnedError
}

Try / catch

try {
  await publishToVibedrop(params) // params.slug set
} catch (e) {
  if (e instanceof VibedropSlugNotOwnedError) {
    // retry without params.slug, or ask user for a new slug
  }
}

Prevention

When it happens

Trigger: Publishing with a slug that exists but is not owned by the current vdKey/account: postJson returns 404 and json.error.code === 'slug_not_owned'. The catch converts this into the typed error.

Common situations: User switched accounts and the cached slug belongs to the old account; slug was claimed by another user; re-publishing after a key/account reset where ownership changed; colliding slug across accounts.

Related errors


AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12). Data as JSON: /api/errors/6c65f3c2c296c219. Report an issue: GitHub.