jackwener/OpenCLI · error · CommandExecutionError

Instagram private mixed-media publish does not support gener

Error message

Instagram private mixed-media publish does not support generating video covers on ${process.platform}

What it means

generateVideoCoverImage extracts a cover frame using AVFoundation/AppKit through a Swift script, so it is macOS-only; on other platforms it throws at clis/instagram/_shared/private-publish.js:471. Like error 1911, this is a deliberate platform guard with the suggestion to use macOS or the UI fallback.

Source

Thrown at clis/instagram/_shared/private-publish.js:471

        throw new CommandExecutionError(`Instagram private publish failed to read video metadata for ${filePath}`);
    }
    return {
        width: metadata.width,
        height: metadata.height,
        durationMs: metadata.durationMs,
    };
}
function buildPrivateVideoCoverPath(filePath) {
    const parsed = path.parse(filePath);
    return path.join(os.tmpdir(), `opencli-instagram-private-video-cover-${parsed.name}-${crypto.randomUUID()}.jpg`);
}
function buildPrivateStoryVideoPath(filePath) {
    const parsed = path.parse(filePath);
    return path.join(os.tmpdir(), `opencli-instagram-story-video-${parsed.name}-${crypto.randomUUID()}${parsed.ext || '.mp4'}`);
}
function generateVideoCoverImage(filePath) {
    if (process.platform !== 'darwin') {
        throw new CommandExecutionError(`Instagram private mixed-media publish does not support generating video covers on ${process.platform}`, 'Use macOS for private mixed-media publishing, or rely on the UI fallback');
    }
    const outputPath = buildPrivateVideoCoverPath(filePath);
    runSwiftJsonScript(`
import AVFoundation
import AppKit
import Foundation

let inputPath = CommandLine.arguments[1]
let outputPath = CommandLine.arguments[2]
let asset = AVURLAsset(url: URL(fileURLWithPath: inputPath))
let generator = AVAssetImageGenerator(asset: asset)
generator.appliesPreferredTrackTransform = true
let image = try generator.copyCGImage(at: CMTime(seconds: 0, preferredTimescale: 600), actualTime: nil)
let rep = NSBitmapImageRep(cgImage: image)
guard let data = rep.representation(using: .jpeg, properties: [.compressionFactor: 0.9]) else {
  fputs("{\\"error\\":\\"jpeg-encode-failed\\"}", stderr)
  exit(1)
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Run the cover generation and publish on macOS
  2. Pre-generate the cover image yourself (e.g. `ffmpeg -i video.mp4 -frames:v 1 cover.jpg`) and pass it instead of letting the library derive it
  3. Use the UI publish flow that has a fallback
  4. Guard with a platform check and route to a different publish mode

Example fix

// before
const cover = await coverImage(videoPath);
// after
const cover = process.platform === 'darwin'
  ? await coverImage(videoPath)
  : { cleanupPath: null, ...generateCoverWithFfmpeg(videoPath) };
Defensive patterns

Strategy: fallback

Validate before calling

if (process.platform !== 'darwin') {
  const { execSync } = require('child_process');
  execSync(`ffmpeg -y -i ${videoPath} -frames:v 1 -q:v 2 ${coverPath}`);
  return { cleanupPath: coverPath, bytes: fs.readFileSync(coverPath) };
}

Try / catch

let cover;
try { cover = await coverImage(videoPath); }
catch (e) {
  if (/does not support generating video covers/.test(e.message)) cover = ffmpegCover(videoPath);
  else throw e;
}

Prevention

When it happens

Trigger: Calling coverImage (via generateVideoCoverImage) while process.platform is 'linux' or 'win32'.

Common situations: Running the private video/story publisher on a Linux server or Windows workstation; CI runners without macOS hosts; Docker-based deployments of an automation that previously ran on a Mac.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/826119a22834c382. Report an issue: GitHub.