dbt-labs/dbt-core · error · anyhow
: : malformed line
Error message
{}:{lineno}: malformed line {:?} What it means
collect_tarballs_from_sha256sums rejects a line of SHA256SUMS that doesn't split into a '<hash> <filename>' pair — there is no whitespace-separated second field, so the tarball filename can't be recovered and the rendered Homebrew formula would embed a broken URL. The message includes file, line number, and the offending line.
Solutions
- Fix the SHA256SUMS line to '<64-hex> <filename>' format
- Regenerate SHA256SUMS from the actual release artifacts
- Skip malformed lines with a warning if strict parsing isn't required
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at crates/dbt-ci/src/homebrew/render.rs:186 when the library encounters an invalid state.
Common situations: See trigger scenarios.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/7d702c6a575e4d35.
Report an issue: GitHub.
Appendix: source
Thrown at crates/dbt-ci/src/homebrew/render.rs:186
/// trailing-whitespace variants). Only lines matching the tarball prefix +
/// version are kept; wheels, zips, etc. are silently skipped.
fn collect_tarballs_from_sha256sums(
path: &Path,
prefix: &str,
version: &str,
) -> Result<Vec<Tarball>> {
let text = fs::read_to_string(path).with_context(|| format!("read {}", path.display()))?;
let leader = format!("{prefix}{version}-");
let mut out = Vec::new();
for (raw, lineno) in text.lines().zip(1u32..) {
let line = raw.trim();
if line.is_empty() || line.starts_with('#') {
continue;
}
// `<hex> <filename>` — split on first whitespace run.
let mut parts = line.splitn(2, char::is_whitespace);
let (Some(sha), Some(rest)) = (parts.next(), parts.next()) else {
bail!("{}:{lineno}: malformed line {:?}", path.display(), raw);
};
if sha.len() != 64 || !sha.chars().all(|c| c.is_ascii_hexdigit()) {
bail!(
"{}:{lineno}: expected 64-char hex sha256, got {:?}",
path.display(),
sha,
);
}
// `sha256sum -b` prepends a single `*` to the filename. Some
// implementations leave extra whitespace before the name. Strip both.
let trimmed = rest.trim_start();
let filename = trimmed.strip_prefix('*').unwrap_or(trimmed);
let Some(after_leader) = filename.strip_prefix(&leader) else {
continue;
};
let Some(target_triple) = after_leader.strip_suffix(".tar.gz") else {
continue;
};View on GitHub (pinned to 0267ce9170)