nexu-io/open-design · error · Error

volcengine poll non-JSON: ${truncate(pollText, 200)}

Error message

volcengine poll non-JSON: ${truncate(pollText, 200)}

What it means

Thrown when `JSON.parse(pollText)` fails on a poll response. Same shape as the creation non-JSON error (424) but on the GET poll path: a 2xx HTML/gateway body instead of the expected `{status, content}` JSON.

Source

Thrown at apps/daemon/src/media/index.ts:1494

  // mid-flight.
  if (typeof onProgress === 'function') {
    const mode = ctx.imageRef ? 'i2v' : 't2v';
    onProgress(`volcengine ${mode} task ${taskId} accepted; polling status…`);
  }
  while (Date.now() - startedAt < maxMs) {
    await sleep(4000);
    const pollResp = await fetch(`${baseUrl}/contents/generations/tasks/${encodeURIComponent(taskId)}`, withMediaRequestInit(ctx, {
      headers: { 'authorization': `Bearer ${credentials.apiKey}` },
    }));
    const pollText = await pollResp.text();
    if (!pollResp.ok) {
      throw new Error(`volcengine poll ${pollResp.status}: ${truncate(pollText, 240)}`);
    }
    let pollData: any;
    try {
      pollData = JSON.parse(pollText);
    } catch {
      throw new Error(`volcengine poll non-JSON: ${truncate(pollText, 200)}`);
    }
    lastStatus = pollData.status || '';
    // Forward each poll tick. Heartbeat doubles as a "command is alive"
    // signal for the agent's bash tool — the daemon's SSE stream emits
    // an event for every line, which cc renders into the chat as live
    // output so its watchdog never marks the call as hung.
    if (typeof onProgress === 'function') {
      const elapsedSec = Math.round((Date.now() - startedAt) / 1000);
      onProgress(`volcengine task ${taskId} status=${lastStatus || 'pending'} (elapsed ${elapsedSec}s)`);
    }
    if (lastStatus === 'succeeded') {
      videoUrl = pollData?.content?.video_url || null;
      break;
    }
    if (lastStatus === 'failed' || lastStatus === 'cancelled') {
      const reason = pollData?.error?.message || lastStatus;
      throw new Error(`volcengine task ${lastStatus}: ${reason}`);
    }

View on GitHub (pinned to 5be4028344)

Solutions

  1. Retry the render; this is typically transient.
  2. Inspect the truncated body to distinguish gateway HTML from a routing error.
  3. Verify baseUrl/host reachability and that no proxy rewrites the response.
Defensive patterns

Strategy: try-catch

Validate before calling

function looksLikeArkJson(text: string): boolean {
  const head = text.slice(0, 100).trim();
  return head.startsWith('{') || head.startsWith('[');
}

Try / catch

try { pollData = JSON.parse(pollText); }
catch { throw new Error(`volcengine poll non-JSON: ${truncate(pollText, 200)}`); }

Prevention

When it happens

Trigger: 2xx poll response that isn't JSON. Gateway maintenance page returned mid-render, proxy HTML interstitial, or a transient HTML body from the Ark edge.

Common situations: (1) Mid-render gateway blip returning HTML; (2) proxy injection; (3) baseUrl misconfiguration.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/cd2c27b5e6005134. Report an issue: GitHub.