facebook/flow · error · std::io::Error

{autofix_error}; additionally failed to stop Flow: {stop_err

Error message

{autofix_error}; additionally failed to stop Flow: {stop_error}

What it means

In flow_dev_tools' check-annotate-exports runtest with autofix enabled, the harness runs the autofix command over the test files and afterwards stops the Flow test server. If BOTH fail, it returns the autofix error annotated with "; additionally failed to stop Flow: {stop_error}". The primary defect is the autofix error printed before the semicolon; the stop error is secondary cleanup noise from an already-unhealthy test session.

Source

Thrown at rust_port/crates/flow_dev_tools/src/runtests/check_annotate_exports.rs:404

        Ok(())
    })();

    let stop_result = exec_file(
        &flow_bin.to_string_lossy(),
        &["stop".to_owned(), ".".to_owned()],
        &ExecOptions {
            cwd: Some(test_dir.clone()),
            env: Some(env.clone()),
            max_buffer: Some(100 * 1024 * 1024),
            ..ExecOptions::default()
        },
        None,
    );
    match (autofix_result, stop_result) {
        (Ok(()), Ok(_)) => {}
        (Err(error), Ok(_)) | (Ok(()), Err(error)) => return Err(error),
        (Err(autofix_error), Err(stop_error)) => {
            return Err(io::Error::new(
                autofix_error.kind(),
                format!("{autofix_error}; additionally failed to stop Flow: {stop_error}"),
            ));
        }
    }

    // Keep copies of autofix-ed files
    for file in &files {
        fs::copy(
            test_dir.join(file),
            test_dir.join(format!("{file}.autofix")),
        )?;
    }

    // Compare autofix-ed with original
    for file in &files {
        let original = fs::read_to_string(test_dir.join(format!("{file}.orig")))?;
        let autofix = fs::read_to_string(test_dir.join(format!("{file}.autofix")))?;

View on GitHub (pinned to 5c86586199)

Solutions

  1. Fix the primary autofix error — the text before '; additionally failed to stop Flow' — by rerunning that autofix command manually to see its full output.
  2. Kill leftover flow server processes and remove stale lock/socket/pids files for the test dir, then rerun the check.
  3. Do not run two runtests sessions against the same test directory at the same time.

Example fix

# before: stale server from a crashed run makes both steps fail
flow runtests check-annotate-exports --autofix $TEST_DIR

# after: clear stale server state, then rerun and read the primary (first) error
pgrep -af flow | xargs -r kill
rm -f "$TEST_DIR"/.flow*lock "$TEST_DIR"/.flow*sock
flow runtests check-annotate-exports --autofix $TEST_DIR
Defensive patterns

Strategy: try-catch

Type guard

fn is_compound_autofix_stop_error(e: &std::io::Error) -> bool {
    e.to_string().contains("additionally failed to stop Flow")
}

Try / catch

When catching this error, split the message on '; additionally failed to stop Flow:' — diagnose and fix the first half (the autofix failure) first; the second half only matters for cleaning up stale server state (kill leftover flow processes, remove lock/socket files) before rerunning.

Prevention

When it happens

Trigger: Running `flow runtests check-annotate-exports --autofix ...` (or the equivalent runtests entry point) where the autofix exec over the test dir exits with an error AND the subsequent server-stop step also fails (server already gone, lock/socket conflict).

Common situations: A test tree with violations the autofix command cannot rewrite; a leftover Flow server from a previously crashed run holding the lock/socket for the test dir; two runtests sessions pointed at the same test directory concurrently.

Related errors


AI-assisted analysis of facebook/flow@5c86586199 (2026-08-20). Data as JSON: /api/errors/5966e39f10fce081. Report an issue: GitHub.