transact-rs/sqlx · error
Invalid `cargo metadata` output
Error message
Invalid `cargo metadata` output
What it means
After `cargo metadata` runs, sqlx parses its stdout as JSON to extract `workspace_root`. This `.expect()` panics when `cargo metadata` produced output that is not valid JSON of the expected shape (e.g. the command emitted warnings/error text or an unexpected format version on stdout).
Source
Thrown at sqlx-macros-core/src/query/metadata.rs:53
use serde::Deserialize;
use std::process::Command;
let cargo = crate::env("CARGO").unwrap();
let output = Command::new(cargo)
.args(["metadata", "--format-version=1", "--no-deps"])
.current_dir(&self.manifest_dir)
.env_remove("__CARGO_FIX_PLZ")
.output()
.expect("Could not fetch metadata");
#[derive(Deserialize)]
struct CargoMetadata {
workspace_root: PathBuf,
}
let metadata: CargoMetadata =
serde_json::from_slice(&output.stdout).expect("Invalid `cargo metadata` output");
*root = Some(metadata.workspace_root);
}
root.clone().unwrap()
}
}
pub fn try_for_crate() -> crate::Result<Arc<Metadata>> {
/// The `MtimeCache` in this type covers the config itself,
/// any changes to which will indirectly invalidate the loaded env vars as well.
#[expect(clippy::type_complexity)]
static METADATA: Mutex<
HashMap<String, Arc<MtimeCache<Arc<Metadata>>>, BuildHasherDefault<DefaultHasher>>,
> = Mutex::new(HashMap::with_hasher(BuildHasherDefault::new()));
let manifest_dir = crate::env("CARGO_MANIFEST_DIR")?;
let cache = METADATAView on GitHub (pinned to 03af8bcc57)
Solutions
- Run `cargo metadata --format-version=1 --no-deps` manually and verify stdout is pure JSON.
- Remove cargo wrappers/aliases that add non-JSON output to stdout.
- Update or align the toolchain (rustup update) so cargo's metadata format matches expectations.
- Rebuild with `cargo clean` to rule out stale cached macro output.
Defensive patterns
Strategy: validation
Validate before calling
// Verify stdout parses as JSON before relying on macro builds:
let out = std::process::Command::new("cargo")
.args(["metadata", "--format-version=1", "--no-deps"]).output().unwrap();
let v: serde_json::Value = serde_json::from_slice(&out.stdout)
.expect("stdout is not valid JSON — check for cargo wrappers printing extra output");
assert!(v.get("workspace_root").is_some()); Prevention
- Remove cargo aliases/wrappers that print anything extra to stdout
- Keep the Rust toolchain up to date so cargo metadata format matches
- Run `cargo metadata --format-version=1 --no-deps | jq .workspace_root` as a sanity check
When it happens
Trigger: Compiling with sqlx macros when `cargo metadata --format-version=1` stdout fails `serde_json::from_slice` — corrupted stderr/stdout mixing, custom cargo wrappers printing extra output, or a cargo version emitting an incompatible format.
Common situations: Wrapper scripts or cargo aliases that print banners to stdout; extremely old/new cargo with format drift; intercepted process output in unusual build environments.
Related errors
- Could not fetch metadata
- downcast to wrong DatabaseError type; original error: {self}
- downcast to wrong DatabaseError type; original error: {e}
- invalid column index: {}
- unimplemented!()
AI-assisted analysis of transact-rs/sqlx@03af8bcc57 (2026-09-03).
Data as JSON: /api/errors/4c7fa26001a78f4f.
Report an issue: GitHub.