zed-industries/zed · error

failed to add stream output

Error message

failed to add stream output: {}

What it means

macOS ScreenCaptureKit rejected the attempt to attach the screen output to an SCStream. When `addStreamOutput:type:sampleHandlerQueue:error:` fails, the capture stream cannot deliver frames, so the error (a localizedDescription from the ObjC layer) is surfaced as an anyhow error through the async channel.

Solutions

  1. Grant Screen Recording permission to the app in System Settings > Privacy & Security > Screen Recording and relaunch
  2. Check the localizedDescription in the message for the specific ScreenCaptureKit error
  3. Verify SCStream configuration (width/height/pixel format) is valid for the target display
  4. Ensure the app runs in an environment with a display and required entitlements

Example fix

// before
if let Err(error) = stream.addStreamOutput_type_sampleHandlerQueue_error(...) { /* send error */ }
// after
if let Err(error) = stream.addStreamOutput_type_sampleHandlerQueue_error(...) {
    _ = sender.send(Err(anyhow!("failed to add stream output: {}; check Screen Recording permission", error.localizedDescription())));
    return receiver;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check screen recording permission (macOS 15+)
let granted = CGPreflightScreenCaptureAccess();
if !granted { panic!("Screen Recording permission required"); }

Type guard

fn stream_output_added(result: &Result<Receiver, anyhow::Error>) -> bool { result.is_ok() }

Try / catch

let receiver = capture::stream(...);
while let Some(event) = receiver.recv().await {
    if let Err(e) = event {
        if e.to_string().contains("failed to add stream output") {
            prompt_screen_recording_permission();
            break;
        }
    }
}

Prevention

When it happens

Trigger: Calling `stream()` in gpui_macos's screen_capture when SCStream output setup fails — e.g. screen recording permission not granted, invalid stream configuration, or the stream was already torn down.

Common situations: First-run without Screen Recording permission in System Settings (TCC denial), running in environments without a display/entitlements, or macOS version where ScreenCaptureKit APIs changed.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of zed-industries/zed@916fc2b8cb (2026-09-19). Data as JSON: /api/errors/92a91f06990a7e39. Report an issue: GitHub.

Appendix: source

Thrown at crates/gpui_macos/src/screen_capture.rs:98

            configuration.setPixelFormat(0x42475241);
            configuration.setWidth(metadata.resolution.width.0 as usize);
            configuration.setHeight(metadata.resolution.height.0 as usize);

            let stream = SCStream::initWithFilter_configuration_delegate(
                SCStream::alloc(),
                &filter,
                &configuration,
                None,
            );
            let output = StreamOutput::new(frame_callback);
            let output_protocol = ProtocolObject::from_ref(&*output);

            if let Err(error) = stream.addStreamOutput_type_sampleHandlerQueue_error(
                output_protocol,
                SCStreamOutputType::Screen,
                None,
            ) {
                _ = sender.send(Err(anyhow!(
                    "failed to add stream output: {}",
                    error.localizedDescription()
                )));

                return receiver;
            }

            let state = Rc::new(RefCell::new(Some((sender, stream.clone(), output))));
            let handler = RcBlock::new(move |error: *mut NSError| {
                let Some((sender, stream, output)) = state.borrow_mut().take() else {
                    return;
                };
                let result = if let Some(error) = error.as_ref() {
                    Err(anyhow!(
                        "failed to start screen capture stream: {}",
                        error.localizedDescription()
                    ))
                } else {

View on GitHub (pinned to 916fc2b8cb)