m1k1o/neko · error
unable to get first image
Error message
unable to get first image
What it means
createPipeline waits on the first sample from the newly created GStreamer pipeline's Sample() channel. If the channel is closed without delivering an image (ok == false), it returns 'unable to get first image'. This means the pipeline was torn down or ended before producing any frame.
Source
Thrown at server/internal/capture/screencast.go:203
manager.logger.Info().
Str("str", manager.pipelineStr).
Msgf("creating pipeline")
manager.pipeline, err = gst.CreatePipeline(manager.pipelineStr)
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
}
View on GitHub (pinned to b0f01cedea)
Solutions
- Retry start/Image after a short delay — transient races usually succeed on the second attempt
- Check that nothing stops or destroys the pipeline concurrently during startup
- Verify the GStreamer pipeline string is valid so the source actually produces samples
- Inspect logs for pipeline teardown messages around the failure time
Example fix
// before
if err := manager.start(); err != nil { return err } // unable to get first image
// after
var err error
for i := 0; i < 3; i++ {
if err = manager.start(); err == nil || !strings.Contains(err.Error(), "first image") { break }
time.Sleep(200 * time.Millisecond)
} Defensive patterns
Strategy: retry
Try / catch
if err := manager.start(); err != nil {
if err.Error() == "unable to get first image" {
// transient: pipeline closed before first sample
time.Sleep(300 * time.Millisecond)
return manager.start() // retry once
}
return err
} Prevention
- Avoid stopping/destroying the pipeline concurrently with startup
- Keep the triggering session alive through the first second after start
- Validate the GStreamer pipeline string emits samples (test with gst-launch)
- Retry start once or twice on this specific error before failing
When it happens
Trigger: The pipeline's sample channel closes during the 1-second wait — typically because the pipeline was stopped/destroyed immediately after creation, or the source ended with no samples emitted.
Common situations: Fast disconnect of the client that triggered pipeline creation races the first-sample wait; faulty GStreamer element chain exits instantly; stopping the stream from another goroutine within the first second.
Related errors
- timeouted while waiting for first image
- image data not found
- screencast not enabled
- (pipeline error) %s
- listener cannot be nil
AI-assisted analysis of m1k1o/neko@b0f01cedea (2026-09-01).
Data as JSON: /api/errors/304952c958362c31.
Report an issue: GitHub.