Stirling-Tools/Stirling-PDF · error · Error

No job ID received from server

Error message

No job ID received from server

What it means

Thrown in PdfTextEditor's async conversion flow when the POST to the conversion endpoint (?async=true&lightweight=true) returns a JSON response without a jobId field. The async conversion protocol requires the server to immediately return { jobId: string } so the client can poll for completion. Without it, the polling loop cannot start.

Source

Thrown at frontend/editor/src/core/tools/pdfTextEditor/PdfTextEditor.tsx:723

          const formData = new FormData();
          formData.append("fileInput", file);

          console.log("Sending conversion request with async=true");
          const response = await apiClient.post(
            `${CONVERSION_ENDPOINTS["pdf-text-editor"]}?async=true&lightweight=true`,
            formData,
            {
              responseType: "json",
            },
          );

          console.log("Conversion response:", response.data);
          const jobId = response.data.jobId;

          if (!jobId) {
            console.error("No job ID in response:", response.data);
            throw new Error("No job ID received from server");
          }

          pendingJobId = jobId;
          console.log("Got job ID:", jobId);
          setConversionProgress({
            percent: 3,
            stage: "processing",
            message: "Starting conversion...",
          });

          let jobComplete = false;
          let attempts = 0;
          const maxAttempts = 600;
          let pollDelay = 500;

          while (!jobComplete && attempts < maxAttempts) {
            await new Promise((resolve) => setTimeout(resolve, pollDelay));
            attempts += 1;

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Check if response.data contains the full conversion result (pages array) — if so, the server doesn't support async mode; fall back to synchronous parsing.
  2. Verify server version supports async conversion (check /api/v1/info or release notes).
  3. Log the full response.data to diagnose the unexpected shape.
  4. Fall back to synchronous mode (remove ?async=true) if jobId is absent but response looks like valid conversion data.

Example fix

// before
const jobId = response.data.jobId;
if (!jobId) {
  throw new Error("No job ID received from server");
}

// after
const jobId = response.data.jobId;
if (!jobId) {
  if (Array.isArray(response.data.pages)) {
    // Server doesn't support async — use synchronous result directly
    parsed = response.data as PdfJsonDocument;
    pendingJobId = null;
  } else {
    throw new Error(`Unexpected server response: ${JSON.stringify(response.data).slice(0, 200)}`);
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// Check if response contains jobId OR a synchronous result
const data = response.data;
if (data.jobId) {
  // async path — proceed with polling
} else if (Array.isArray(data.pages)) {
  // sync path — server doesn't support async, use result directly
  parsed = data as PdfJsonDocument;
} else {
  throw new Error(`Unexpected conversion response: ${JSON.stringify(data).slice(0, 200)}`);
}

Type guard

function hasJobId(data: unknown): data is { jobId: string } {
  return typeof data === 'object' && data !== null && typeof (data as any).jobId === 'string';
}

Try / catch

try {
  const response = await apiClient.post(endpoint, formData, { responseType: 'json' });
  if (!response.data.jobId && !Array.isArray(response.data.pages)) {
    throw new Error('Server returned unexpected conversion response.');
  }
} catch (error) {
  setErrorMessage(`Failed to start conversion: ${error instanceof Error ? error.message : 'unknown'}`);
}

Prevention

When it happens

Trigger: The server version doesn't support the async=true query parameter and returned a synchronous response (the full PDF JSON directly). Or the server returned an error object without a jobId field. Or the endpoint returned an unexpected schema.

Common situations: Server/client version mismatch — client expects async protocol but server is older and only supports synchronous. Server returned { error: '...' } or { status: 'failed' } without a jobId. Network proxy stripped or modified the response.

Related errors


AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13). Data as JSON: /api/errors/19f9c4b01ab5ed16. Report an issue: GitHub.