chatboxai/chatbox · error · Error
Failed to publish to VibeDrop (status ${status})
Error message
Failed to publish to VibeDrop (status ${status}) What it means
Thrown by publishToVibedrop() as the catch-all when the response status is >= 400 (after auth and slug cases are handled) OR when status is 2xx but json.site.url is missing. It is the generic VibeDrop publish failure, preferring the server's error.message and falling back to a status-coded string.
Source
Thrown at src/renderer/packages/vibedrop.ts:107
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]
if (!payload) return null
const json = JSON.parse(atob(payload.replace(/-/g, '+').replace(/_/g, '/')))
return typeof json.email === 'string' && json.email ? json.email.toLowerCase() : nullView on GitHub (pinned to 81571269ad)
Solutions
- Read the embedded server error.message — it usually states the specific validation/limit problem.
- For 429, wait and retry with backoff.
- For 5xx, retry after a short delay; if persistent, check VibeDrop status.
- If the body shape is unexpected, confirm the VibeDrop API version matches the client.
Defensive patterns
Strategy: retry
Validate before calling
function looksPublishable(status: number, json: unknown): boolean {
return status < 400 && !!json && typeof (json as any)?.site?.url === 'string'
} Type guard
function isVibedropPublishSuccess(json: unknown): json is { site: { slug: string; url: string; visibility: string } } {
return !!json && typeof json === 'object' && typeof (json as any).site?.url === 'string'
} Try / catch
try {
await publishToVibedrop(params)
} catch (e) {
if (e instanceof Error && /Failed to publish to VibeDrop/.test(e.message)) {
// inspect server message; retry with backoff for 429/5xx
}
} Prevention
- Distinguish 429/5xx (retryable) from 4xx validation (fix input).
- Read the embedded server error.message before retrying.
- Confirm VibeDrop API version compatibility after backend changes.
When it happens
Trigger: postJson returns any status >= 400 not already handled (e.g. 400 validation, 429 rate limit, 500), or a successful status whose body lacks json.site.url. The guard `if (status >= 400 || !json?.site?.url) throw ...` fires.
Common situations: Validation errors (invalid visibility/title), rate limiting, server-side 5xx, malformed response shape after a backend change, partial outage returning 200 with empty body.
Related errors
- VibeDrop authorization failed
- HTML content is empty, nothing to publish.
- slug no longer owned
- Knowledge base name cannot be empty
- Invalid pagination parameters
AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12).
Data as JSON: /api/errors/e667682be62e2513.
Report an issue: GitHub.