rust-lang/rust · error · anyhow::Error

unexpected end of input inside <text> block

Error message

unexpected end of input inside <text> block

What it means

Thrown by resolve_multiline_value in the SPDX tag-value parser when a value begins with <text> but the iterator of remaining lines ends without a line containing the closing </text> tag. Per the SPDX spec, multi-line values must be wrapped in <text>…</text>; an unclosed tag means the document is truncated or malformed.

Source

Thrown at src/tools/collect-license-metadata/src/spdx/mod.rs:84

    };

    // The closing tag might be on the same line.
    if let Some(content) = start.strip_suffix("</text>") {
        return Ok(content.to_string());
    }

    let mut text = start.to_string();
    for line in further_lines.by_ref() {
        if let Some(rest) = line.strip_suffix("</text>") {
            text.push('\n');
            text.push_str(rest);
            return Ok(text);
        }
        text.push('\n');
        text.push_str(line);
    }

    anyhow::bail!("unexpected end of input inside <text> block")
}

fn build_file_entry(
    name: String,
    concluded_license: Option<String>,
    copyright_text: Option<String>,
) -> Result<SpdxFileEntry, Error> {
    Ok(SpdxFileEntry {
        name,
        concluded_license: concluded_license
            .ok_or_else(|| anyhow::anyhow!("file missing LicenseConcluded"))?,
        copyright_text: copyright_text
            .ok_or_else(|| anyhow::anyhow!("file missing FileCopyrightText"))?,
    })
}

#[cfg(test)]
mod tests;

View on GitHub (pinned to 7088e4b63a)

Solutions

  1. Re-run REUSE to regenerate the SPDX document and check whether the truncation recurs.
  2. Inspect the REUSE stdout around the offending tag to confirm whether the closing </text> is missing or merely split across buffers.
  3. Upgrade REUSE if a known bug produced malformed output.
  4. If parsing a hand-edited SPDX file, add the missing </text> closing tag.

Example fix

null
Defensive patterns

Strategy: validation

Validate before calling

// Quick well-formedness check: every <text> tag has a matching </text>.
let opens = input.matches("<text>").count();
let closes = input.matches("</text>").count();
if opens != closes {
    eprintln!("SPDX input has {opens} <text> opens but {closes} </text> closes; likely truncated");
}

Try / catch

match crate::spdx::parse_tag_value(raw) {
    Ok(files) => files,
    Err(e) if e.to_string().contains("inside <text> block") => {
        eprintln!("SPDX document appears truncated; regenerate with REUSE.");
        return Err(e);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: REUSE produced an SPDX document where a <text> block (e.g. a multi-line FileCopyrightText) was cut off before its closing tag; the document was truncated in transit or by a buffering issue; an unterminated <text> on the last line of the file.

Common situations: REUSE output truncated due to a large repo or a pipe buffer limit; a bug in the REUSE version producing malformed SPDX; manual editing of an SPDX document removing the closing tag.

Understand the failure class

Related errors


AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10). Data as JSON: /api/errors/9cab735d661763d9. Report an issue: GitHub.