stablyai/orca · error
Simulator stream must target stream.mjpeg.
Error message
Simulator stream must target stream.mjpeg.
What it means
normalizeStreamUrl requires the pathname to end with /stream.mjpeg so the JPEG frame extractor receives MJPEG bytes rather than arbitrary content. A bare host:port or the /ax path would feed the wrong content-type to the parser.
Source
Thrown at src/main/emulator/mjpeg-frame-stream.ts:21
import { extractJpegFrames } from './mjpeg-frame-parser'
const RECONNECT_DELAY_MS = 1_000
const REQUEST_TIMEOUT_MS = 10_000
const MAX_FPS = 30
const MIN_FRAME_INTERVAL_MS = Math.floor(1_000 / MAX_FPS)
export type MjpegFrameStreamCallbacks = {
onError: (message: string) => void
onFrame: (frame: Buffer<ArrayBufferLike>) => void
}
function normalizeStreamUrl(streamUrl: string, streamKey?: string): URL {
const url = new URL(streamUrl)
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
throw new Error('Simulator stream must use http or https.')
}
if (!url.pathname.endsWith('/stream.mjpeg')) {
throw new Error('Simulator stream must target stream.mjpeg.')
}
url.searchParams.set('raw', '1')
if (streamKey) {
url.searchParams.set('_orca', streamKey)
}
return url
}
function requestForUrl(url: URL, response: (res: IncomingMessage) => void): ClientRequest {
return (url.protocol === 'https:' ? httpsRequest : httpRequest)(
url,
{
headers: {
Accept: 'application/octet-stream, image/jpeg'
},
timeout: REQUEST_TIMEOUT_MS
},
responseView on GitHub (pinned to 1136503c6a)
Solutions
- Append `/stream.mjpeg` to the serve-sim base URL.
- Use streamUrlFromServeSimUrl() to derive the correct path.
- Use the session's pre-parsed `streamUrl` rather than constructing the URL by hand.
Example fix
// before
new MjpegFrameStream('http://localhost:8080', cb)
// after
new MjpegFrameStream('http://localhost:8080/stream.mjpeg', cb) Defensive patterns
Strategy: validation
Validate before calling
if (!streamUrl.endsWith('/stream.mjpeg')) { streamUrl = `${streamUrl.replace(/\/$/, '')}/stream.mjpeg` } Type guard
function isStreamPathError(e: unknown): boolean {
return e instanceof Error && /must target stream\.mjpeg/.test(e.message)
} Try / catch
try { new MjpegFrameStream(url, cb) }
catch (e) { if (isStreamPathError(e)) { url = streamUrlFromServeSimUrl(url); new MjpegFrameStream(url, cb) } else throw e } Prevention
- Use the session's pre-parsed streamUrl.
- Derive paths with streamUrlFromServeSimUrl() rather than string concatenation.
- Never pass the /ax endpoint to the frame stream.
When it happens
Trigger: Constructing MjpegFrameStream with a URL whose pathname does not end in '/stream.mjpeg' (mjpeg-frame-stream.ts:19-21).
Common situations: Passing the serve-sim base URL (http://host:port) without the suffix; passing the /ax endpoint by mistake; manually building the URL instead of using the parsed session field.
Related errors
- Simulator stream must use http or https.
- linear_invalid_url
- Localhost label target is not a valid URL.
- Package version is not valid semver: ${baseVersion}
- Adhoc build timestamp is invalid.
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/603b869a48bcf76a.
Report an issue: GitHub.