Skip to content

Instantly share code, notes, and snippets.

@GarthDB
Last active September 11, 2025 17:08
Show Gist options
  • Select an option

  • Save GarthDB/c2a65e4b37bdf76c60cfedadc2e5845c to your computer and use it in GitHub Desktop.

Select an option

Save GarthDB/c2a65e4b37bdf76c60cfedadc2e5845c to your computer and use it in GitHub Desktop.
Octocrab E0716 Lifetime Issue - Complete Example with Solution

Octocrab E0716 Lifetime Issue Reproduction

This is a minimal reproduction of the E0716: temporary value dropped while borrowed error that occurs when using octocrab's builder pattern for creating GitHub issues.

The Problem

The current octocrab API forces users to store intermediate values to avoid lifetime issues, which goes against the ergonomic builder pattern that Rust developers expect.

How to Reproduce

  1. Clone this repository or copy the files
  2. Run cargo check or cargo run
  3. Observe the E0716 compilation error (when uncommented)

Expected Error

error[E0716]: temporary value dropped while borrowed
  --> src/main.rs:25:29
   |
25 |     let mut issue_builder = client.issues(owner, repo).create(title);
   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                     - temporary value is freed at the end of this statement
   |                             |
   |                             creates a temporary value which is freed while still in use
...
28 |     issue_builder = issue_builder.body(body);
   |                     ^^^^^^^^^^^^^ borrow later used here

Current Workaround

// Store the intermediate value to extend its lifetime
let issues_client = client.issues(owner, repo);
let issue_builder = issues_client
    .create(title)
    .body(body)
    .labels(labels);
issue_builder.send().await?;

Proposed Solution

The octocrab library should return owned types from builder methods instead of references, allowing for ergonomic method chaining:

// This should work without lifetime issues
let issue = client.issues(owner, repo)
    .create(title)
    .body(body)
    .labels(labels)
    .send()
    .await?;

Clippy Analysis

After implementing the workaround, the code passes all clippy lints including clippy::pedantic:

cargo clippy -- -W clippy::pedantic

The workaround does not introduce any clippy warnings or errors, making it a clean solution for the lifetime issue.

Related

Environment

  • octocrab: 0.36.0
  • Rust: 1.75.0+
  • OS: Any
[package]
name = "octocrab-e0716-example"
version = "0.1.0"
edition = "2021"
description = "Complete example demonstrating E0716 lifetime issue in octocrab with recommended solution"
[[bin]]
name = "main"
path = "main.rs"
[dependencies]
octocrab = "0.36"
tokio = { version = "1.0", features = ["full"] }

Octocrab E0716 Lifetime Issue - Complete Example

This gist demonstrates the E0716: temporary value dropped while borrowed error that occurs when using octocrab's builder pattern for creating GitHub issues, along with the recommended solution.

The Problem

When chaining octocrab issue builder methods, you get this error:

let mut issue_builder = client.issues(owner, repo).create(title);
// ❌ E0716: temporary value dropped while borrowed
issue_builder = issue_builder.body(body);
issue_builder = issue_builder.labels(labels);

The Solution

Store the intermediate value to extend its lifetime:

let issues_client = client.issues(owner, repo);
let issue_builder = issues_client
    .create(title)
    .body(body)
    .labels(labels);
// βœ… This works without lifetime issues

How to Run

  1. Copy the files to a new Rust project
  2. Run cargo run to see the demonstration
  3. Run cargo clippy -- -W clippy::pedantic to verify no warnings

Related

// Octocrab E0716 Lifetime Issue - Complete Example with Solution
//
// This demonstrates the E0716 "temporary value dropped while borrowed" error
// and provides the recommended workaround solution.
//
// Issue: https://github.com/XAMPPRocky/octocrab/issues/796
//
// To run: cargo run
// To check with clippy: cargo clippy -- -W clippy::pedantic
use octocrab::Octocrab;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Octocrab::builder()
.personal_token("your_token_here".to_string())
.build()?;
let owner = "octocrab-rs";
let repo = "octocrab";
let title = "Test Issue";
let body = "This is a test issue body";
let labels = vec!["bug".to_string(), "enhancement".to_string()];
println!("πŸ” Demonstrating octocrab E0716 lifetime issue and solution\n");
// ❌ THIS FAILS WITH E0716: temporary value dropped while borrowed
//
// Error: temporary value is freed at the end of this statement
// The issue is that client.issues(owner, repo) returns a temporary value
// that gets dropped at the end of the statement, but issue_builder still
// holds a reference to it.
println!("❌ This approach fails with E0716 error:");
println!(" let mut issue_builder = client.issues(owner, repo).create(title);");
println!(" issue_builder = issue_builder.body(body);");
println!(" issue_builder = issue_builder.labels(labels);");
println!();
// βœ… RECOMMENDED SOLUTION: Store the intermediate value to extend its lifetime
// This is the workaround suggested by dmgorsky in the GitHub issue
println!("βœ… Recommended solution (dmgorsky's workaround):");
println!(" let issues_client = client.issues(owner, repo);");
println!(" let issue_builder = issues_client");
println!(" .create(title)");
println!(" .body(body)");
println!(" .labels(labels);");
println!();
let issues_client = client.issues(owner, repo);
let _issue_builder = issues_client
.create(title)
.body(body)
.labels(labels.clone());
// Now we can use the builder without lifetime issues
println!("βœ… Issue builder created successfully!");
println!(" Title: {title}");
println!(" Body: {body}");
println!(" Labels: {labels:?}");
println!();
// πŸš€ IDEAL SOLUTION: What we'd like to see in octocrab
// If octocrab returned owned types from builder methods, this would work:
println!("πŸš€ Ideal solution (if octocrab returned owned types):");
println!(" let issue = client.issues(owner, repo)");
println!(" .create(title)");
println!(" .body(body)");
println!(" .labels(labels)");
println!(" .send()");
println!(" .await?;");
println!();
println!("πŸ“ Summary:");
println!("- E0716 error occurs due to temporary value lifetime issues");
println!("- Workaround: Store intermediate client to extend lifetime");
println!("- Ideal: octocrab should return owned types from builder methods");
println!("- This solution passes all clippy lints including clippy::pedantic");
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment