{"record":{"id":"bcd07dba22614f9c","repo":"moeru-ai/airi","slug":"no-output-received-from-replicate","errorCode":null,"errorMessage":"No output received from Replicate.","messagePattern":"No output received from Replicate\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/stage-tamagotchi/src/main/services/airi/widgets/providers/replicate.ts","lineNumber":137,"sourceCode":"\n    // We don't await the result here because the interface expects us to return an ArtistryJob immediately.\n    // However, replicate.run() blocks until completion. We'll run it in the background and store the result.\n    const jobId = request.extra?.internalJobId || Math.random().toString(36).slice(2)\n\n    // Start generation asynchronously\n    this.runGeneration(jobId, model, inputOptions)\n\n    return { jobId, providerJobId: jobId }\n  }\n\n  private async runGeneration(jobId: string, model: `${string}/${string}`, input: object) {\n    this.updateStatus(jobId, { status: 'running', actionLabel: 'Requesting cloud generation...' })\n\n    try {\n      const output = await this.replicate!.run(model, { input })\n\n      if (!output) {\n        throw new Error('No output received from Replicate.')\n      }\n\n      log.log(`[Replicate] Raw output type: ${typeof output}, isArray: ${Array.isArray(output)}`)\n\n      // Replicate's run() can return a single string, an array of strings, or an array of FileUpload objects\n      const items = Array.isArray(output) ? output : [output]\n      if (items.length > 0) {\n        const first = items[0]\n        let imageUrl: string | undefined\n\n        // Case 1: FileUpload object with .url() method (common in recent SDK versions)\n        if (typeof first === 'object' && first !== null && 'url' in first && typeof (first as any).url === 'function') {\n          imageUrl = (first as any).url().href\n        }\n        // Case 2: Object with url property as a string\n        else if (typeof first === 'object' && first !== null && 'url' in first && typeof (first as any).url === 'string') {\n          imageUrl = (first as any).url\n        }","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/moeru-ai/airi/blob/27111382b4a79a7e983289d6e983a06af185ed0f/apps/stage-tamagotchi/src/main/services/airi/widgets/providers/replicate.ts#L119-L155","documentation":"Thrown inside runGeneration after `await this.replicate!.run(model, { input })` returns a falsy value (null/undefined). The Replicate SDK resolved the prediction but produced no output payload at all, which the provider treats as a hard failure rather than an empty success. Distinct from [43] which handles an empty array, and [42] which handles an unrecognized shape.","triggerScenarios":"Replicate returns a resolved prediction whose `output` field is null/undefined — can happen when the model errored server-side but still HTTP-200'd, when a model version was deprecated mid-run, or when rate limiting caused a degenerate response.","commonSituations":"Model `owner/model` slug was retired or renamed; prediction succeeded but the model wrote no output file; transient Replicate platform incident; using a text model slug on an image input path.","solutions":["Check the Replicate dashboard for the prediction status of the failing run (the SDK swallows the prediction id here — add logging of the raw prediction object).","Confirm defaultModel / requested model slug still exists and is an image-output model on replicate.com.","Retry once — null output is frequently transient on Replicate.","If recurring, switch to a known-good model (e.g. black-forest-labs/flux-schnell) to isolate model vs platform."],"exampleFix":"// before\nconst output = await this.replicate!.run(model, { input })\nif (!output) {\n  throw new Error('No output received from Replicate.')\n}\n\n// after\nconst output = await this.replicate!.run(model, { input })\nif (!output) {\n  throw new Error(`No output received from Replicate for model ${model}. Check prediction status.`)\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":"function hasReplicateOutput(output: unknown): output is NonNullable<typeof output> {\n  return output != null\n}","tryCatchPattern":"let output\nfor (let attempt = 0; attempt < 2; attempt++) {\n  output = await provider.replicate.run(model, { input })\n  if (output) break\n  await new Promise(r => setTimeout(r, 1000))\n}\nif (!output) throw new Error('No output received from Replicate.')","preventionTips":["Log the raw prediction object (not just run()'s return) to capture server-side status.","Retry once — null output is frequently transient.","Validate the model slug exists on replicate.com before defaulting to it."],"tags":["replicate","network","artistry","upstream"],"backgroundTag":null,"analyzedSha":"27111382b4a79a7e983289d6e983a06af185ed0f","analyzedAt":"2026-08-12T18:33:34.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}