Skip to content

Fix HTTP headers to include headers from Step Scope (Step.headers → HttpProbe.headers)#27

Merged
thearyanahmed merged 1 commit into
thearyanahmed:masterfrom
rafidoth:fix-http-probe-missing-headers
Jun 5, 2026
Merged

Fix HTTP headers to include headers from Step Scope (Step.headers → HttpProbe.headers)#27
thearyanahmed merged 1 commit into
thearyanahmed:masterfrom
rafidoth:fix-http-probe-missing-headers

Conversation

@rafidoth

@rafidoth rafidoth commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Blueprint .bp files currently define HTTP headers inside step scope using a headers { ... } block.
However, during transpilation those headers are stored only in Step.headers, while HttpProbe.headers remains empty.

As a result, HTTP probes execute without the intended request headers.

Problem

Given a blueprint like:

blueprint "Test" {
    phase "test" {
        step "user agent" {
            probe http GET /user-agent
            headers { User-Agent: test-agent/1.0 }
            expect {
                status: 200
                body: "test-agent/1.0"
            }
        }
    }
}
  • headers are parsed from step scope (Step.headers)
  • probe http ... resolves to Probe::Http(HttpProbe { headers: HashMap::new(), ... })
  • executor (crates/blueprint/src/executor/probes/http.rs) sends only probe.headers
    let mut builder = match probe.method {
        HttpMethod::GET => client.get(url),
        HttpMethod::POST => client.post(url),
        HttpMethod::PUT => client.put(url),
        HttpMethod::DELETE => client.delete(url),
        HttpMethod::PATCH => client.patch(url),
        HttpMethod::HEAD => client.head(url),
        HttpMethod::OPTIONS => client.request(reqwest::Method::OPTIONS, url),
    };


    for (k, v) in &probe.headers {
        let v = ctx.interpolate(v);
        builder = builder.header(k, v);
    }

So requests are sent without step-defined headers.


Root Cause

Scope mismatch between transpiler and executor:

  • Transpiler puts headers in Step.headers
  • Executor reads headers from HttpProbe.headers
  • No transfer/merge happens between the two

Solution (implemented in this PR)

Adopted Approach 2: move headers from step scope to HTTP probe scope during transpilation.

What changed

In crates/blueprint/src/transpiler/resolve.rs (resolve_step):

  • After resolving the probe, if probe type is HTTP:
    • move headers into HttpProbe.headers using std::mem::take
  • Keep non-HTTP probe behavior unchanged

This ensures headers defined in step scope are available where execution expects them.


Alternatives considered

  1. Change blueprint syntax/design (define headers inline on probe)

    • Rejected for now: Architectural Decision
  2. Move headers during transpilation ✅ (chosen)

  3. Inject/override headers at execution time from Step

    • Rejected: executor currently operates on probe-level data; introducing step-to-probe coupling at runtime is not clean/feasible in current structure.

Tests

Added regression test in crates/blueprint/src/transpiler/resolve.rs:

  • test_http_step_headers_are_moved_into_probe_headers

Validates that:

  • step-level headers { ... } are present in Probe::Http.headers
  • Step.headers is empty after move (no duplication)

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request fixes a scope mismatch in the blueprint transpiler so that HTTP request headers declared in step scope (headers { ... }) are actually applied by the HTTP probe executor (which reads from HttpProbe.headers).

Changes:

  • In resolve_step, move step-level headers into HttpProbe.headers when the step’s probe is HTTP.
  • Add a regression test ensuring headers end up on Probe::Http.headers and are removed from Step.headers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@thearyanahmed thearyanahmed merged commit 65a0e77 into thearyanahmed:master Jun 5, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants