kopia/kopia · error

error marshaling computed snapshot diff stats

Error message

error marshaling computed snapshot diff stats

What it means

Wraps a failure of json.Marshal(snapshotDiffStats) after a successful directory comparison in `kopia diff`. marshaling a well-formed diff stats struct essentially never fails in practice, so this indicates an internal invariant violation or an unsupported value sneaking into the stats (e.g. NaN/Inf from division in stats computation).

Solutions

  1. Re-run on a stock kopia build to rule out local modifications
  2. If reproducible, file a bug with the repository/directory pair involved
  3. Work around by using stats-only or non-directory diff output

Example fix

// before
b, err := json.Marshal(snapshotDiffStats)
if err != nil {
	return errors.Wrap(err, "error marshaling computed snapshot diff stats")
}
// after
b, err := json.Marshal(snapshotDiffStats)
if err != nil {
	log(ctx).Errorf("diff stats: %+v", snapshotDiffStats)
	return errors.Wrap(err, "error marshaling computed snapshot diff stats")
}
Defensive patterns

Strategy: try-catch

Try / catch

b, err := json.Marshal(snapshotDiffStats)
if err != nil {
	log.Printf("diff stats marshal failed: %v; stats=%+v", err, snapshotDiffStats)
	return errors.Wrap(err, "error marshaling computed snapshot diff stats")
}

Prevention

When it happens

Trigger: Directory-mode diff completes, but json.Marshal of the snapshotDiffStats value returns an error — practically only when the stats struct contains values JSON cannot represent or a programming defect changes the struct.

Common situations: Rare; encountered after custom builds/patches to the diff stats types, or in the presence of NaN/Inf values produced by stat calculations.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07). Data as JSON: /api/errors/dc698d69c270d2e9. Report an issue: GitHub.

Appendix: source

Thrown at cli/command_diff.go:77

		return errors.Wrap(err, "error creating comparer")
	}
	defer d.Close() //nolint:errcheck

	if c.diffCompareFiles {
		parts := strings.Split(c.diffCommandCommand, " ")
		d.DiffCommand = parts[0]
		d.DiffArguments = parts[1:]
	}

	if isDir1 {
		snapshotDiffStats, err := d.Compare(ctx, ent1, ent2)
		if err != nil {
			return errors.Wrap(err, "error comparing directories")
		}

		b, err := json.Marshal(snapshotDiffStats)
		if err != nil {
			return errors.Wrap(err, "error marshaling computed snapshot diff stats")
		}

		fmt.Fprintf(c.out.stdout(), "%s", b) //nolint:errcheck

		return nil
	}

	return errors.New("comparing files not implemented yet")
}

func defaultDiffCommand() string {
	if isWindows() {
		return "cmp"
	}

	return "diff -u"
}

View on GitHub (pinned to 82495e54b5)