{"record":{"id":"2321fcff0fea7f30","repo":"chatboxai/chatbox","slug":"html-content-is-empty-nothing-to-publish","errorCode":null,"errorMessage":"HTML content is empty, nothing to publish.","messagePattern":"HTML content is empty, nothing to publish\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/renderer/packages/vibedrop.ts","lineNumber":91,"sourceCode":"      if (e instanceof ApiError && typeof e.statusCode === 'number') {\n        return { status: e.statusCode, json: safeJson(e.responseBody) }\n      }\n      throw e\n    }\n  }\n  const response = await ofetch.raw<InlinePublishResponse>(url, {\n    method: 'POST',\n    headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${bearer}` },\n    body,\n    ignoreResponseError: true,\n  })\n  return { status: response.status, json: response._data ?? null }\n}\n\nexport async function publishToVibedrop(params: PublishToVibedropParams): Promise<VibedropSite> {\n  const { html, vdKey, title, visibility, slug } = params\n  if (!html?.trim()) {\n    throw new Error('HTML content is empty, nothing to publish.')\n  }\n\n  const body: Record<string, unknown> = { html, visibility }\n  if (title) body.title = title\n  if (slug) body.slug = slug\n\n  const { status, json } = await postJson(`${VIBEDROP_API_ORIGIN}/v1/sites/inline`, body, vdKey)\n\n  if (status === 401 || status === 403) {\n    throw new VibedropAuthError(json?.error?.message || 'VibeDrop authorization failed')\n  }\n  if (status === 404 && json?.error?.code === 'slug_not_owned') {\n    throw new VibedropSlugNotOwnedError('slug no longer owned')\n  }\n  if (status >= 400 || !json?.site?.url) {\n    throw new Error(json?.error?.message || `Failed to publish to VibeDrop (status ${status})`)\n  }\n","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/chatboxai/chatbox/blob/81571269addb6bafb589a920b2883f1e1e084fd1/src/renderer/packages/vibedrop.ts#L73-L109","documentation":"Thrown by publishToVibedrop() when the html parameter is missing or whitespace-only (after html?.trim()). It prevents posting an empty page to VibeDrop and is the earliest validation before the network request is built.","triggerScenarios":"Calling publishToVibedrop with html = '', html = '   ', or html = undefined/null. The guard `if (!html?.trim()) throw ...` fires before postJson.","commonSituations":"The HTML generator returned empty due to an upstream error; a template produced only whitespace; the publish button was enabled with no content generated; programmatic call with an unset html variable.","solutions":["Ensure the html content is a non-empty, non-whitespace string before publishing.","Fix the upstream HTML generator if it returns empty.","Disable the publish action until content is non-empty."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function hasHtmlContent(html: string | undefined | null): boolean {\n  return typeof html === 'string' && html.trim().length > 0\n}\nif (!hasHtmlContent(html)) {\n  // disable publish; do not call publishToVibedrop\n}","typeGuard":"function isNonEmptyHtml(html: unknown): html is string {\n  return typeof html === 'string' && html.trim().length > 0\n}","tryCatchPattern":"try {\n  await publishToVibedrop(params)\n} catch (e) {\n  if (e instanceof Error && e.message === 'HTML content is empty, nothing to publish.') {\n    // regenerate content before publishing\n  }\n}","preventionTips":["Generate and validate HTML before enabling publish.","Treat empty generator output as an error upstream.","Disable publish in the UI until content exists."],"tags":["vibedrop","validation","publish","user-input"],"backgroundTag":null,"analyzedSha":"81571269addb6bafb589a920b2883f1e1e084fd1","analyzedAt":"2026-08-12T21:51:44.981Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}