GitoxideLabs/gitoxide · error

we prohibit this

Error message

we prohibit this

What it means

`gix_merge::blob::Pipeline::convert_to_mergeable()` applies worktree filters (e.g. CRLF conversion, clean filters) to make a blob mergeable. The library panics if the filter machinery returns `ToWorktreeOutcome::Process(MaybeDelayed::Delayed(_))`, i.e. a deferred/delayed processing result, because the pipeline's configuration prohibits delayed processing in this path. Hitting it means the delayed-pipeline prohibition was violated.

Solutions

  1. Build the `gix_filter` pipeline (or `gix::filter::Pipeline`) without delayed process support so filters return immediate results during merge.
  2. Remove or reconfigure `filter.<driver>.process` entries in git config that enable delayed processing for the involved drivers.
  3. Use a merge path where worktree filters are disabled, or convert blobs explicitly with a non-delayed pipeline before merging.
  4. If it occurs with default configuration, report upstream with the `.gitattributes` and filter config used.

Example fix

// before
let pipeline = gix::filter::Pipeline::new(repo)?; // may use delayed process drivers
let blob = pipeline.convert_to_mergeable(blob, rela_path)?;

// after
let pipeline = gix::filter::Pipeline::new(repo)?
    .with_driver_process_handling(gix::filter::driver::process::Handling::Error); // disable delayed handling
let blob = pipeline.convert_to_mergeable(blob, rela_path)?;
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the filter pipeline is not configured for delayed processing before merging
if pipeline.supports_delayed_process() {
    return Err(anyhow::anyhow!("merge path prohibits delayed filter processes; disable process filters for this driver"));
}

Type guard

fn is_immediate(outcome: &ToWorktreeOutcome) -> bool {
    matches!(outcome, ToWorktreeOutcome::Process(MaybeDelayed::Immediate(_)) | ToWorktreeOutcome::Buffer(_))
}

Try / catch

// Guard the filter result before the pipeline asserts:
match filter_outcome {
    ToWorktreeOutcome::Process(MaybeDelayed::Delayed(_)) => {
        return Err(anyhow::anyhow!("delayed filter processing not allowed during merge"));
    }
    other => { /* proceed */ }
}

Prevention

When it happens

Trigger: Calling `convert_to_mergeable` (directly or via `without_transformation`/`binary_below_large_file_threshold`/`non_existing`) while the underlying `gix_filter` pipeline was built with a delayed process (e.g. a long-running filter process supporting delayed responses), so `convert_to_worktree` yields a `Delayed` outcome.

Common situations: Configuring the filter pipeline with driver processes that advertise delayed operation (multiple-driver setups with `gix_filter::driver::Process` supporting delays) and then running blob merges; usually arises after enabling process-based filters in `.gitattributes`/driver configuration.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08). Data as JSON: /api/errors/e109eb48a7d45ab9. Report an issue: GitHub.

Appendix: source

Thrown at gix-merge/src/blob/pipeline.rs:308

                                )?;

                                match res {
                                    ToWorktreeOutcome::Unchanged(_) => {}
                                    ToWorktreeOutcome::Buffer(src) => {
                                        out.clear();
                                        out.try_reserve(src.len())?;
                                        out.extend_from_slice(src);
                                    }
                                    ToWorktreeOutcome::Process(MaybeDelayed::Immediate(mut stream)) => {
                                        std::io::copy(&mut stream, out).map_err(|err| {
                                            convert_to_mergeable::Error::StreamCopy {
                                                rela_path: rela_path.to_owned(),
                                                source: err,
                                            }
                                        })?;
                                    }
                                    ToWorktreeOutcome::Process(MaybeDelayed::Delayed(_)) => {
                                        unreachable!("we prohibit this")
                                    }
                                }
                            }

                            let res = self.filter.convert_to_git(
                                &**out,
                                &gix_path::from_bstr(rela_path),
                                attributes,
                                &mut |_buf| Ok(None),
                            )?;

                            match res {
                                ToGitOutcome::Unchanged(_) => {}
                                ToGitOutcome::Process(mut stream) => {
                                    stream
                                        .read_to_end(out)
                                        .map_err(|err| convert_to_mergeable::Error::OpenOrRead {
                                            rela_path: rela_path.to_owned(),

View on GitHub (pinned to e73179060b)