m1k1o/neko · error

timeouted while waiting for first image

Error message

timeouted while waiting for first image

What it means

createPipeline waits up to 1 second (time.After) for the first image on the pipeline's Sample() channel. If no sample arrives within that window, it returns 'timeouted while waiting for first image'. The library uses this bounded wait so a broken/silent capture source cannot block startup forever.

Source

Thrown at server/internal/capture/screencast.go:208

	if err != nil {
		return err
	}

	manager.pipeline.AttachAppsink("appsink")
	manager.pipeline.Play()
	manager.pipelinesCounter.Inc()
	manager.pipelinesActive.Set(1)

	// get first image
	select {
	case image, ok := <-manager.pipeline.Sample():
		if !ok {
			return errors.New("unable to get first image")
		} else {
			manager.setImage(image)
		}
	case <-time.After(1 * time.Second):
		return errors.New("timeouted while waiting for first image")
	}

	pipeline := manager.pipeline
	manager.wg.Go(func() {
		manager.logger.Debug().Msg("started receiving images")

		for {
			image, ok := <-pipeline.Sample()
			if !ok {
				manager.logger.Debug().Msg("stopped receiving images")
				return
			}

			manager.setImage(image)
		}
	})

	return nil

View on GitHub (pinned to b0f01cedea)

Solutions

  1. Retry start — under load the first frame may simply be slow; consider increasing the 1s timeout in a fork/patch
  2. Validate the GStreamer pipeline string (caps, framerate, encoder) produces samples with gst-launch
  3. Check the display/capture source is actually producing frames (not blank/locked/headless without a capture backend)
  4. Reduce system load or pre-warm the pipeline before the first request

Example fix

// before
case <-time.After(1 * time.Second):
    return errors.New("timeouted while waiting for first image")
// after
case <-time.After(5 * time.Second): // allow slow sources to emit first frame
    return errors.New("timeouted while waiting for first image")
Defensive patterns

Strategy: retry

Validate before calling

// Pre-check: ensure the capture source is alive and system not overloaded before starting.
// (Library has no pre-check API; treat timeout as retryable.)
if err := checkCaptureSourceAvailable(); err != nil {
    return err
}

Try / catch

if err := manager.start(); err != nil {
    if err.Error() == "timeouted while waiting for first image" {
        // slow source: retry with longer overall budget
        for i := 0; i < 3; i++ {
            time.Sleep(500 * time.Millisecond)
            if err = manager.start(); err == nil { break }
        }
    }
    return err
}

Prevention

When it happens

Trigger: The newly created GStreamer pipeline does not emit any sample within 1 second — slow source startup, encoder stalls, wrong pipeline string, or a device that produces no frames.

Common situations: Heavy load or slow machine where the encoder takes >1s to produce the first frame; misconfigured pipeline element (wrong framerate/caps) yielding no samples; headless or locked display where the capture source never emits.

Understand the failure class

Related errors


AI-assisted analysis of m1k1o/neko@b0f01cedea (2026-09-01). Data as JSON: /api/errors/f471ce1605b53129. Report an issue: GitHub.