{"record":{"id":"b11ae0b894b8f645","repo":"nexu-io/open-design","slug":"vela-image-command-returned-non-ready-asset-sta","errorCode":null,"errorMessage":"Vela image ${command} returned non-ready asset status ${status ?? 'missing'}","messagePattern":"Vela image (.+?) returned non-ready asset status (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/daemon/src/media/vela.ts","lineNumber":392,"sourceCode":"        ? ['--aspect-ratio', profile.aspectRatio, '--resolution', profile.resolution]\n        : []),\n      ...quality,\n      '--output',\n      outputPath,\n      '--json',\n    ];\n    const stdout = await runCommand(args, {\n      ...velaWorkspaceCommandOptions(input.workspaceId),\n      timeoutMs: VELA_IMAGE_TIMEOUT_MS,\n    });\n    const asset = parseJsonObject(stdout, `image ${command}`);\n    const assetId = nonEmptyString(asset.asset_id);\n    const status = nonEmptyString(asset.status);\n    const kind = nonEmptyString(asset.kind);\n    const mime = nonEmptyString(asset.mime_type);\n    if (!assetId) throw new Error(`Vela image ${command} response is missing asset_id`);\n    if (status !== 'ready') {\n      throw new Error(`Vela image ${command} returned non-ready asset status ${status ?? 'missing'}`);\n    }\n    if (kind !== 'image') {\n      throw new Error(`Vela image ${command} returned unexpected kind ${kind ?? 'missing'}`);\n    }\n    if (!mime?.startsWith('image/')) {\n      throw new Error(`Vela image ${command} returned invalid mime_type ${mime ?? 'missing'}`);\n    }\n    const bytes = await readNonEmptyOutput(outputPath, `image ${command}`);\n    return {\n      bytes,\n      // The tier is part of what the user was charged for, so name it when it\n      // was chosen and say so plainly when the server's default decided.\n      providerNote: `vela/${wireModel} · ${\n        profile ? `${profile.aspectRatio} ${profile.resolution}` : 'model default profile'\n      } · ${requestedQuality ?? 'model default quality'} · ${bytes.length} bytes`,\n      suggestedExt: extensionForImageMime(mime),\n    };\n  } finally {","sourceCodeStart":374,"sourceCodeEnd":410,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/media/vela.ts#L374-L410","documentation":"Thrown after confirming asset_id when asset.status is not the string 'ready'. Vela's image gen/edit is synchronous; a non-ready status means the asset exists but is not in a deliverable state (e.g. 'failed', 'pending', 'error'). The actual status (or 'missing' if absent) is shown.","triggerScenarios":"Vela image gen/edit JSON has a status field that is anything other than 'ready' — for example 'failed', 'error', 'pending', 'moderated', or an empty/missing status.","commonSituations":"Upstream generation failed (content policy, model error) but Vela still returned an asset envelope; transient moderation hold; CLI emitted a pre-ready status; Vela bug.","solutions":["Read the embedded status value — 'failed'/'error' usually means retry with a different prompt","For 'pending'/'moderated', retry after a short delay","Run the Vela command directly to see the full asset envelope and any stderr detail","If the status is unexpected for the CLI version, check for a schema change"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"function assetIsReady(asset: Record<string, unknown>): boolean {\n  return asset.status === 'ready';\n}","typeGuard":"function isReadyAsset(asset: unknown): boolean {\n  return typeof asset === 'object' && asset !== null\n    && (asset as { status?: unknown }).status === 'ready';\n}","tryCatchPattern":"try {\n  if (!isReadyAsset(asset)) throw new Error(`non-ready status: ${asset.status ?? 'missing'}`);\n} catch (err) {\n  if (/non-ready/.test(String((err as Error).message))) {\n    // retry for pending/moderated, or fail with a user-facing message for failed/error\n  } else throw err;\n}","preventionTips":["Inspect the status value to decide retry vs fail — pending may resolve, failed usually will not","Capture the full asset envelope so moderation or error reasons are diagnosable","Add retries only for transient statuses, not for 'failed'/'error'"],"tags":["vela","response","status","upstream"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}