Profiles·Public

replicate

semver>=0.16.0postconditions13functions8last verified2026-04-16coverage score100%

Postconditions — what we check

  • run · run-no-error-handling
    error
    Whenreplicate.run() called without try-catch or .catch() handler
    ThrowsApiError on HTTP errors (401 Unauthorized, 402 Payment Required, 404 Not Found, 422 Unprocessable). Error("Prediction failed: <detail>") if the model errors during execution (prediction.status === "failed"). Network errors: ECONNREFUSED, ETIMEDOUT.
    Required handlingCaller MUST wrap await replicate.run() in try-catch or chain .catch(). Uncaught error causes unhandled promise rejection — API routes crash, users see 500 errors, inference results are silently lost. try { const output = await replicate.run("owner/model", { input: { prompt: "..." } }); return output; } catch (error) { console.error("Replicate run error:", error); throw error; }
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][2]
  • run · run-prediction-failure-swallowed
    error
    Whenreplicate.run() call catches error generically and returns null/undefined or continues silently when prediction.status === "failed"
    ThrowsError("Prediction failed: <model-error-message>") — contains the model's error detail from the prediction object. This is a distinct error type from ApiError (HTTP errors). It is thrown when the model itself reports a failure (GPU OOM, model crash, E1001 out-of-memory, invalid input processed by model).
    Required handlingDistinguish between ApiError (auth/network/rate-limit — infrastructure failure) and Error with "Prediction failed:" prefix (model-level failure — may be retryable with different inputs). Swallowing this error means the caller returns undefined output which downstream code treats as valid.
    costmediumin prodimmediate exceptionusers seedegraded performancevisibilitysilent
    Sources[1][2]
  • stream · stream-no-error-handling
    error
    Whenfor-await loop over replicate.stream() is not wrapped in try-catch
    ThrowsApiError (from internal predictions.create() call) for HTTP errors: 401 (bad API token), 402 (no credits), 404 (model not found), 422 (invalid inputs). Error("Invalid model version identifier") if the model ref is malformed. Error("Prediction does not support streaming") if the model version lacks an SSE endpoint — not all models support streaming, only those with stream: true in their schema. Network errors propagate as-is.
    Required handlingCaller MUST wrap the for-await loop in try-catch. Stream errors can surface partway through iteration (e.g., model OOM mid-generation). The error from predictions.create() is thrown synchronously before iteration begins. try { for await (const event of replicate.stream("owner/model", { input: { prompt: "..." } })) { process.stdout.write(event.data); } } catch (error) { if (error instanceof Replicate.ApiError) { console.error("API error:", error.response.status, error.message); } else { console.error("Stream error:", error.message); } }
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][3]
  • stream · stream-model-not-streaming-capable
    warning
    Whenreplicate.stream() called on a model that does not support streaming (model version lacks an SSE endpoint URL in prediction.urls.stream)
    ThrowsError("Prediction does not support streaming") — thrown after predictions.create() succeeds (HTTP 200) but before any SSE events are yielded. The prediction was created and is consuming billing credits, but the caller receives no output. Streaming support depends on individual model version, not the model itself.
    Required handlingCheck model capabilities before calling stream(). If streaming is not guaranteed, use run() or predictions.create() + wait() instead. Catching "Prediction does not support streaming" and falling back to run() is a safe recovery pattern. Note: the prediction created internally is not automatically canceled on this error — it may continue running in the background.
    costlowin prodimmediate exceptionusers seedegraded performancevisibilityvisible
    Sources[1][3]
  • wait · wait-prediction-failure
    error
    Whenreplicate.wait() is not wrapped in try-catch, or catch only handles ApiError but not plain Error (prediction failure is a plain Error, not ApiError)
    ThrowsError("Prediction failed: <model-error-message>") — thrown when prediction reaches status "failed". This is a plain Error, NOT an ApiError. Catching only (error instanceof ApiError) will miss this. The error message contains the model's error string (e.g., "CUDA out of memory", "Invalid input"). Also throws ApiError if predictions.get() HTTP call fails during polling.
    Required handlingCaller MUST catch both ApiError (infrastructure/HTTP failures during polling) and plain Error (model execution failure). A catch-all is sufficient: try { const completed = await replicate.wait(prediction); return completed.output; } catch (error) { if (error instanceof Replicate.ApiError) { console.error("Polling failed:", error.response.status); } else { // Model execution failed — error.message = "Prediction failed: <reason>" console.error("Model failed:", error.message); } throw error; }
    costmediumin prodimmediate exceptionusers seedegraded performancevisibilitysilent
    Sources[1]
  • wait · wait-canceled-prediction-not-thrown
    warning
    WhenCode checks only for output after replicate.wait() without checking prediction.status, assuming resolved wait() always means success
    ThrowsDoes NOT throw on canceled predictions (status === "canceled") — wait() returns the prediction object silently. Code that does "const result = await replicate.wait(pred); return result.output" will return undefined/null if prediction was canceled without any exception. Only "failed" status throws — "canceled" is a silent non-throw return.
    Required handlingAfter wait() resolves without throwing, check prediction.status === "succeeded" before accessing output. Canceled predictions have no output. const completed = await replicate.wait(prediction); if (completed.status !== "succeeded") { throw new Error(`Prediction ${completed.status}: ${completed.error || 'no output'}`); } return completed.output;
    costlowin prodsilent failureusers seelost datavisibilitysilent
    Sources[1]
  • trainings.create · trainings-create-no-error-handling
    error
    Whenreplicate.trainings.create() called without try-catch
    ThrowsError("Invalid webhook URL") — thrown synchronously before any HTTP call if options.webhook is provided but is not a valid URL. ApiError with response.status: 401 (API token invalid), 402 (no credits), 404 (model owner/name/version_id not found), 422 (invalid training input or model does not support fine-tuning), 429 (rate limit).
    Required handlingCaller MUST wrap await replicate.trainings.create() in try-catch. CRITICAL: trainings.create() resolves immediately with a Training object (status: "starting") — the training has NOT completed. Callers must use the returned training.id to poll trainings.get() or configure a webhook. Treating the returned Training as containing the trained model is a bug. try { const training = await replicate.trainings.create( "stability-ai", "sdxl", "version-id-here", { destination: "my-org/my-fine-tuned-model", input: { train_data_url: "...", steps: 1000 } } ); // training.status is "starting" — NOT complete! // Poll training.id or wait for webhook } catch (error) { console.error("Training creation failed:", error); throw error; }
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[4][5]
  • trainings.create · trainings-create-result-not-polled
    error
    WhenCode uses training.output or training.status === "succeeded" immediately after replicate.trainings.create() without waiting for job completion
    ThrowsDoes NOT throw — training.status is "starting" at creation time, training.output is undefined. Code that destructures training.output.version immediately after create() returns undefined silently. Fine-tuning jobs take minutes to hours. The trained model version ID is only available in training.output.version AFTER the job completes.
    Required handlingAlways track training.id and poll or use webhooks for completion: // WRONG — output is undefined immediately after create() const training = await replicate.trainings.create(...); const versionId = training.output.version; // undefined! // RIGHT — poll for completion let completed = await replicate.wait(training); const versionId = completed.output?.version;
    costhighin prodsilent failureusers seelost datavisibilitysilent
    Sources[4][5]
  • predictions.create · predictions-create-no-error-handling
    error
    Whenreplicate.predictions.create() called without try-catch or .catch() handler
    ThrowsError("Invalid webhook URL") synchronously if options.webhook is malformed. ApiError with HTTP status 401 (invalid token), 402 (no credits), 404 (model/version not found), 422 (invalid inputs), 429 (rate limit). Network errors: ECONNREFUSED, ETIMEDOUT.
    Required handlingCaller MUST wrap await replicate.predictions.create() in try-catch or chain .catch(). Note: the returned prediction may also have prediction.error set for model-level failures after creation. try { const prediction = await replicate.predictions.create({ version: "abc123...", input: { prompt: "..." }, webhook: "https://example.com/webhooks/replicate", webhook_events_filter: ["completed"], }); return prediction; } catch (error) { console.error("Replicate prediction error:", error); throw error; }
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[6][7]
  • files.create · files-create-no-error-handling
    error
    Whenreplicate.files.create() called without try-catch
    ThrowsError("Invalid file argument, must be a Blob, File or Buffer") — thrown synchronously before any HTTP call if file is not a Blob or Buffer. ApiError with response.status: 401 (invalid API token), 402 (no credits/storage quota), 413 (file exceeds 100MiB limit — Payload Too Large), 422 (invalid metadata structure), 429 (rate limit).
    Required handlingCaller MUST wrap await replicate.files.create() in try-catch. Handle file size validation before upload to avoid 413 errors. Files expire and must be re-uploaded if the FileObject.expires_at has passed. try { const fileBlob = new Blob([fileBuffer], { type: "image/png" }); const fileObj = await replicate.files.create(fileBlob, { filename: "input.png" }); // Use fileObj.id as model input const output = await replicate.run("owner/model", { input: { image: fileObj.urls.get } }); } catch (error) { console.error("File upload failed:", error); throw error; }
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[8][9]
  • deployments.predictions.create · deployments-predictions-create-no-error-handling
    error
    Whenreplicate.deployments.predictions.create() called without try-catch
    ThrowsError("Invalid webhook URL") synchronously if options.webhook is malformed. ApiError with response.status: 401 (bad API token), 403 (no access to deployment), 404 (deployment owner/name not found or deployment deleted), 422 (invalid prediction inputs), 429 (rate limit on deployment). Note: 403 is deployment-specific (access control) vs 401 (API token).
    Required handlingCaller MUST wrap in try-catch. Deployments can be deleted while code is running — 404 must be handled. In multi-tenant apps, 403 indicates the deployment is not accessible with the current API token. try { const prediction = await replicate.deployments.predictions.create( "my-org", "my-deployment", { input: { prompt: "..." }, wait: 30 } ); if (prediction.status === "succeeded") { return prediction.output; } return await replicate.wait(prediction); } catch (error) { if (error instanceof Replicate.ApiError && error.response.status === 404) { throw new Error("Deployment not found — may have been deleted"); } throw error; }
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[10][11]
  • validateWebhook · validatewebhook-return-value-not-checked
    error
    WhenvalidateWebhook() return value is not checked — code processes the webhook payload regardless of whether signature is valid
    ThrowsDoes NOT throw for invalid signatures — returns false. Code that does "await validateWebhook(req, secret); processWebhook(body)" without checking the return value will process forged/tampered webhooks silently. The function is designed to return false, not throw, for security reasons (avoids timing-attack information leakage from exception messages).
    Required handlingALWAYS check the return value of validateWebhook(). Treating unverified webhooks as legitimate is a security vulnerability — forged webhooks can trigger billing, data changes, or model deployments. const isValid = await validateWebhook(request, secret); if (!isValid) { return new Response("Invalid signature", { status: 401 }); } // Only process verified webhook here const payload = await request.json();
    costhighin prodsilent failureusers seeauthentication failurevisibilitysilent
    Sources[12][13]
  • validateWebhook · validatewebhook-missing-headers-throws
    warning
    WhenvalidateWebhook() called on a request missing webhook-id, webhook-timestamp, or webhook-signature headers (e.g., called on a non-Replicate request or when testing with a plain Request object without headers)
    ThrowsError("Missing required webhook headers") — thrown when any of webhook-id, webhook-timestamp, or webhook-signature headers are absent from the request. Error("Missing required secret") — thrown when the secret argument is falsy. Error("Invalid body type") — thrown when request.body is not a string, Blob, Buffer, ReadableStream, or TypedArray. These throw synchronously before any HMAC computation.
    Required handlingWrap validateWebhook() in try-catch in webhook handler endpoints. Missing header errors indicate the request is not a Replicate webhook (e.g., a health check probe hitting the webhook endpoint). These should return 400 rather than 500. try { const isValid = await validateWebhook(request, webhookSecret); if (!isValid) return new Response("Unauthorized", { status: 401 }); } catch (error) { if (error.message === "Missing required webhook headers") { return new Response("Not a valid webhook request", { status: 400 }); } throw error; }
    costlowin prodimmediate exceptionusers seedegraded performancevisibilityvisible
    Sources[12]

Sources

Every postcondition cites at least one of these. Numbered to match the footnotes above.

  1. [1]github.com/replicate/replicate-javascripthttps://github.com/replicate/replicate-javascript/blob/main/index.js
  2. [2]replicate.com/docs/referencehttps://replicate.com/docs/reference/error-codes
  3. [3]replicate.com/docs/topicshttps://replicate.com/docs/topics/predictions/streaming
  4. [4]github.com/replicate/replicate-javascripthttps://github.com/replicate/replicate-javascript/blob/main/lib/trainings.js
  5. [5]replicate.com/docs/guideshttps://replicate.com/docs/guides/fine-tuning
  6. [6]github.com/replicate/replicate-javascripthttps://github.com/replicate/replicate-javascript/blob/main/lib/predictions.js
  7. [7]replicate.com/docs/referencehttps://replicate.com/docs/reference/http#create-a-prediction
  8. [8]github.com/replicate/replicate-javascripthttps://github.com/replicate/replicate-javascript/blob/main/lib/files.js
  9. [9]github.com/replicate/replicate-javascripthttps://github.com/replicate/replicate-javascript#readme
  10. [10]github.com/replicate/replicate-javascripthttps://github.com/replicate/replicate-javascript/blob/main/lib/deployments.js
  11. [11]replicate.com/docs/topicshttps://replicate.com/docs/topics/deployments
  12. [12]github.com/replicate/replicate-javascripthttps://github.com/replicate/replicate-javascript/blob/main/lib/util.js
  13. [13]replicate.com/docs/topicshttps://replicate.com/docs/topics/webhooks#verifying-webhooks
Need a different package?
Request a profile