nexu-io/open-design · error · Error

Vela image ${command} returned invalid mime_type ${mime ?? '

Error message

Vela image ${command} returned invalid mime_type ${mime ?? 'missing'}

What it means

Thrown after the kind check when asset.mime_type is absent or does not start with 'image/'. This validates the asset is an image before the daemon tries to map the mime to a file extension (error 486 then handles the narrower format check). The actual mime_type (or 'missing') is shown.

Source

Thrown at apps/daemon/src/media/vela.ts:398

    ];
    const stdout = await runCommand(args, {
      ...velaWorkspaceCommandOptions(input.workspaceId),
      timeoutMs: VELA_IMAGE_TIMEOUT_MS,
    });
    const asset = parseJsonObject(stdout, `image ${command}`);
    const assetId = nonEmptyString(asset.asset_id);
    const status = nonEmptyString(asset.status);
    const kind = nonEmptyString(asset.kind);
    const mime = nonEmptyString(asset.mime_type);
    if (!assetId) throw new Error(`Vela image ${command} response is missing asset_id`);
    if (status !== 'ready') {
      throw new Error(`Vela image ${command} returned non-ready asset status ${status ?? 'missing'}`);
    }
    if (kind !== 'image') {
      throw new Error(`Vela image ${command} returned unexpected kind ${kind ?? 'missing'}`);
    }
    if (!mime?.startsWith('image/')) {
      throw new Error(`Vela image ${command} returned invalid mime_type ${mime ?? 'missing'}`);
    }
    const bytes = await readNonEmptyOutput(outputPath, `image ${command}`);
    return {
      bytes,
      // The tier is part of what the user was charged for, so name it when it
      // was chosen and say so plainly when the server's default decided.
      providerNote: `vela/${wireModel} · ${
        profile ? `${profile.aspectRatio} ${profile.resolution}` : 'model default profile'
      } · ${requestedQuality ?? 'model default quality'} · ${bytes.length} bytes`,
      suggestedExt: extensionForImageMime(mime),
    };
  } finally {
    await rm(tempDir, { recursive: true, force: true });
  }
}

export async function renderVelaVideo(
  input: VelaVideoRenderInput,

View on GitHub (pinned to 5be4028344)

Solutions

  1. Run the Vela image command directly and inspect the mime_type field
  2. Confirm the model produces image output for that command
  3. Check the Vela CLI version for a mime_type field rename
  4. Update the response parser if the field name changed
Defensive patterns

Strategy: type-guard

Validate before calling

function assetHasImageMime(asset: Record<string, unknown>): boolean {
  return typeof asset.mime_type === 'string' && asset.mime_type.startsWith('image/');
}

Type guard

function hasImageMime(asset: unknown): asset is { mime_type: string } {
  return typeof asset === 'object' && asset !== null
    && typeof (asset as { mime_type?: unknown }).mime_type === 'string'
    && ((asset as { mime_type: string }).mime_type.startsWith('image/'));
}

Try / catch

try {
  if (!hasImageMime(asset)) throw new Error(`invalid mime_type: ${asset.mime_type ?? 'missing'}`);
} catch (err) {
  // verify the model produces image output; capture full response for diagnosis
}

Prevention

When it happens

Trigger: Vela image gen/edit JSON has a mime_type field that is missing, empty, or a non-image type (e.g. 'video/mp4', 'application/octet-stream').

Common situations: Vela returned a non-image asset under an image command; mime_type field renamed in a newer CLI version; model rollout changed output type; upstream bug returning a placeholder mime.

Related errors


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