{"record":{"id":"304952c958362c31","repo":"m1k1o/neko","slug":"unable-to-get-first-image","errorCode":null,"errorMessage":"unable to get first image","messagePattern":"unable to get first image","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/internal/capture/screencast.go","lineNumber":203,"sourceCode":"\tmanager.logger.Info().\n\t\tStr(\"str\", manager.pipelineStr).\n\t\tMsgf(\"creating pipeline\")\n\n\tmanager.pipeline, err = gst.CreatePipeline(manager.pipelineStr)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tmanager.pipeline.AttachAppsink(\"appsink\")\n\tmanager.pipeline.Play()\n\tmanager.pipelinesCounter.Inc()\n\tmanager.pipelinesActive.Set(1)\n\n\t// get first image\n\tselect {\n\tcase image, ok := <-manager.pipeline.Sample():\n\t\tif !ok {\n\t\t\treturn errors.New(\"unable to get first image\")\n\t\t} else {\n\t\t\tmanager.setImage(image)\n\t\t}\n\tcase <-time.After(1 * time.Second):\n\t\treturn errors.New(\"timeouted while waiting for first image\")\n\t}\n\n\tpipeline := manager.pipeline\n\tmanager.wg.Go(func() {\n\t\tmanager.logger.Debug().Msg(\"started receiving images\")\n\n\t\tfor {\n\t\t\timage, ok := <-pipeline.Sample()\n\t\t\tif !ok {\n\t\t\t\tmanager.logger.Debug().Msg(\"stopped receiving images\")\n\t\t\t\treturn\n\t\t\t}\n","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/m1k1o/neko/blob/b0f01cedea68893e85a3fd852c0521238c285695/server/internal/capture/screencast.go#L185-L221","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nif err := manager.start(); err != nil { return err } // unable to get first image\n// after\nvar err error\nfor i := 0; i < 3; i++ {\n    if err = manager.start(); err == nil || !strings.Contains(err.Error(), \"first image\") { break }\n    time.Sleep(200 * time.Millisecond)\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := manager.start(); err != nil {\n    if err.Error() == \"unable to get first image\" {\n        // transient: pipeline closed before first sample\n        time.Sleep(300 * time.Millisecond)\n        return manager.start() // retry once\n    }\n    return err\n}","preventionTips":["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"],"tags":["go","gstreamer","screencast","pipeline"],"backgroundTag":"empty-capture-stream","analyzedSha":"b0f01cedea68893e85a3fd852c0521238c285695","analyzedAt":"2026-09-01T10:35:56.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}