python/cpython · error · Error

d3-flame-graph library failed to load

Error message

d3-flame-graph library failed to load

What it means

Raised by _ProactorBaseWritePipeTransport.write() when a sendfile operation (loop.sendfile / _sendfile_native) is currently in progress on the transport. During sendfile the transport parks an '_empty_waiter' future and ordinary buffered writes are forbidden because they would interleave with the file transfer. It is a transient, state-based error caused by concurrent use of one transport from two tasks.

Source

Thrown at Lib/profiling/sampling/_flamegraph_assets/flamegraph.js:537

    if (this._tooltip) {
      this._tooltip.transition().duration(150).style("opacity", 0);
    }
    clearStatusBar();
  };

  return pythonTooltip;
}

// ============================================================================
// Flamegraph Creation
// ============================================================================

function ensureLibraryLoaded() {
  if (typeof flamegraph === "undefined") {
    console.error("d3-flame-graph library not loaded");
    document.getElementById("chart").innerHTML =
      '<div style="padding: 40px; text-align: center; color: var(--text-muted);">Error: d3-flame-graph library failed to load</div>';
    throw new Error("d3-flame-graph library failed to load");
  }
}

const HEAT_THRESHOLDS = [
  [0.6, 8],
  [0.35, 7],
  [0.18, 6],
  [0.12, 5],
  [0.06, 4],
  [0.03, 3],
  [0.01, 2],
];

function getHeatLevel(percentage) {
  for (const [threshold, level] of HEAT_THRESHOLDS) {
    if (percentage >= threshold) return level;
  }
  return 1;

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Await the sendfile() coroutine fully before issuing any write() on the same transport
  2. Restructure so a single task owns the transport: serialize writes and sendfile through one writer coroutine or an asyncio.Lock
  3. If interleaving is intentional, use sock_sendfile via raw socket API or write the file in chunks with write() instead of sendfile()
  4. Catch RuntimeError with a retry-after-awaiting-drain only if you can confirm sendfile has completed

Example fix

# before
asyncio.create_task(loop.sendfile(tr, f))
tr.write(b'next request')  # RuntimeError: sendfile in progress
# after
await loop.sendfile(tr, f)
tr.write(b'next request')
Defensive patterns

Strategy: validation

Validate before calling

async def send_file_then_write(loop, tr, f, payload):
    await loop.sendfile(tr, f)      # fully awaited: no in-progress window
    tr.write(payload)

Try / catch

try:
    tr.write(data)
except RuntimeError as e:
    if 'sendfile is in progress' in str(e):
        await asyncio.sleep(0)  # let sendfile progress; real fix is sequencing
        raise

Prevention

When it happens

Trigger: Calling transport.write() (directly or via a writer) while loop.sendfile(transport, file, ...) is still running on the same transport on a Windows proactor event loop. Also triggered by any custom use of the internal _empty_waiter mechanism.

Common situations: A server task streams a file with sendfile while another task writes headers/keepalives on the same connection; benchmark or copy utilities that mix sendfile with manual writes; code that assumes sendfile returns after queuing rather than after completion (not awaiting it).

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/453ace15cece8327. Report an issue: GitHub.