GyulyVGC/sniffnet · error · SystemExit
debian/changelog must match the tagged Cargo.toml version
Error message
debian/changelog must match the tagged Cargo.toml version
What it means
prepare_staged() cross-checks the version parsed from debian/changelog against the 'package.version' field of Cargo.toml at the commit the corresponding git tag (v<version>) points to. If the tagged manifest's version differs from the changelog version, the script aborts, because the Debian source package would claim a version that does not match the upstream code it packages.
Solutions
- Make Cargo.toml's package.version in the commit tagged v<version> equal the changelog version, then re-tag (git tag -f vX.Y.Z && git push -f origin vX.Y.Z)
- Update debian/changelog to the version that the existing tag actually carries
- Verify the tag points at the intended commit: git rev-parse --verify refs/tags/vX.Y.Z^{commit}
Example fix
// before (Cargo.toml at tag v1.3.1) version = "1.3.0" # after version = "1.3.1" # then: git add Cargo.toml && git commit && git tag -f v1.3.1
Defensive patterns
Strategy: validation
Validate before calling
version = re.search(r"sniffnet \(([^)]+)\)", changelog_text).group(1).rsplit("-", 1)[0]
commit = subprocess.run(["git", "rev-parse", "--verify", f"refs/tags/v{version}^{{commit}}"],
capture_output=True, text=True, check=True).stdout.strip()
cargo_version = tomllib.loads(subprocess.run(["git", "show", f"{commit}:Cargo.toml"],
capture_output=True, text=True, check=True).stdout)["package"]["version"]
if cargo_version != version:
raise SystemExit(f"Tag v{version} has Cargo.toml version {cargo_version}; align before packaging") Type guard
def versions_are_consistent(changelog_version: str, cargo_version: str) -> bool:
return changelog_version == cargo_version Try / catch
try:
prepare(output)
except SystemExit as e:
if "must match the tagged Cargo.toml version" in str(e):
print("Bump Cargo.toml (or the changelog) and re-tag: git tag -f vX.Y.Z", file=sys.stderr)
raise Prevention
- Bump Cargo.toml and debian/changelog in the same release commit before tagging
- Never move release tags after the changelog entry is written
- Add a CI check comparing Cargo.toml version with debian/changelog for each tag
- Use a release script that updates both files atomically
When it happens
Trigger: Running prepare.py when debian/changelog says e.g. 1.3.1 but refs/tags/v1.3.1's Cargo.toml has version '1.3.0' — i.e. the changelog was bumped without tagging a matching release, the tag points at the wrong commit, or Cargo.toml version was edited after tagging.
Common situations: Bumping debian/changelog for a release before creating the git tag; tagging a release but forgetting to bump Cargo.toml in the tagged commit; a Debian revision suffix (-1) being handled but the base version diverging from the tag; moving a tag to a different commit after the changelog was written.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
AI-assisted analysis of GyulyVGC/sniffnet@592a62a5ad (2026-09-18).
Data as JSON: /api/errors/08875070460ee882.
Report an issue: GitHub.
Appendix: source
Thrown at resources/packaging/linux/deb-source/prepare.py:51
for path in Path(staging).iterdir():
shutil.move(str(path), output / path.name)
print(f"Release files: {output}", flush=True)
return output / source.name
def prepare_staged(output):
changelog = (DEBIAN / "changelog").read_text()
match = re.match(r"sniffnet \(([^)]+)\) ([\w-]+);", changelog)
if not match:
raise SystemExit("Cannot parse debian/changelog")
version = match[1].rsplit("-", 1)[0]
tag = f"refs/tags/v{version}"
commit = run("git", "rev-parse", "--verify", f"{tag}^{{commit}}",
capture_output=True, text=True).stdout.strip()
manifest = tomllib.loads(run("git", "show", f"{commit}:Cargo.toml",
capture_output=True, text=True).stdout)
if manifest["package"]["version"] != version:
raise SystemExit("debian/changelog must match the tagged Cargo.toml version")
source = output / f"sniffnet-{version}"
archive = output / f"sniffnet_{version}.orig.tar.gz"
if source.exists() or archive.exists():
raise SystemExit(f"Refusing to overwrite an existing release in {output}; use --output with a fresh directory")
epoch = int(run("git", "show", "-s", "--format=%ct", commit,
capture_output=True, text=True).stdout)
output.mkdir(parents=True, exist_ok=True)
source.mkdir()
# Extract only release-tag inputs. A branch with the same name cannot win
# ref resolution, and local application edits cannot enter the package.
snapshot = run("git", "archive", "--format=tar", commit,
capture_output=True).stdout
run("tar", "-xf", "-", cwd=source, input=snapshot)
# Overlay current Debian packaging after creating the upstream archive.
if (source / "debian").exists():
shutil.rmtree(source / "debian")
print(f"Upstream tag: {tag}\nUpstream commit: {commit}", flush=True)View on GitHub (pinned to 592a62a5ad)