kopia/kopia · error

unable to encode directory JSON

Error message

unable to encode directory JSON

What it means

WriteDirManifest could not JSON-encode the DirManifest into the repository object writer, so the rewritten directory manifest was not persisted and object.EmptyID is returned. Callers (processDirectoryEntries, uploads, rewrites) surface this as a failure to write the directory.

Solutions

  1. Check the inner wrapped error; if it is an io.Writer error, treat it as an object-write/storage problem and check repository health.
  2. Ensure DirManifestBuilder was populated with valid DirEntry values (no nil pointers or corrupt ObjectIDs).
  3. Upgrade Kopia if a built-in type fails to marshal — for standard structs this indicates a bug.
  4. Retry the write after resolving any transient storage issues; content-addressed writes are safe to retry.
Defensive patterns

Strategy: validation

Validate before calling

if len(dirManifest.Entries) == 0 && !allowEmpty { return errors.New("refusing to write empty dir manifest") }

Type guard

func writableManifest(dm snapshot.DirManifest) bool {
    for _, e := range dm.Entries {
        if e == nil || e.ObjectID == "" { return false }
    }
    return true
}

Try / catch

oid, err := snapshotfs.WriteDirManifest(ctx, rep, prevOID, dm, comp)
if err != nil {
    if strings.Contains(err.Error(), "unable to encode directory JSON") {
        log.Printf("manifest encoding failed: %+v", err)
    }
    return object.EmptyID, err
}

Prevention

When it happens

Trigger: json.NewEncoder(writer).Encode(dirManifest) returns an error inside WriteDirManifest — the DirManifest struct failed to serialize before being uploaded as a directory object.

Common situations: A DirManifest containing entries with data that breaks JSON encoding (custom marshaler bugs, extremely deep/huge manifests hitting resource limits), or an object-writer-level fault surfaced through the encoder's io.Writer.

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/b5859740f6bd7b2e. Report an issue: GitHub.

Appendix: source

Thrown at snapshot/snapshotfs/dir_writer.go:27

	"github.com/kopia/kopia/repo"
	"github.com/kopia/kopia/repo/compression"
	"github.com/kopia/kopia/repo/object"
	"github.com/kopia/kopia/snapshot"
)

// WriteDirManifest writes a directory manifest to the repository and returns the object ID.
func WriteDirManifest(ctx context.Context, rep repo.RepositoryWriter, dirRelativePath string, dirManifest *snapshot.DirManifest, metadataComp compression.Name) (object.ID, error) {
	writer := rep.NewObjectWriter(ctx, object.WriterOptions{
		Description:        "DIR:" + dirRelativePath,
		Prefix:             objectIDPrefixDirectory,
		Compressor:         metadataComp,
		MetadataCompressor: metadataComp,
	})

	defer writer.Close() //nolint:errcheck

	if err := json.NewEncoder(writer).Encode(dirManifest); err != nil {
		return object.EmptyID, errors.Wrap(err, "unable to encode directory JSON")
	}

	oid, err := writer.Result()
	if err != nil {
		return object.EmptyID, errors.Wrap(err, "unable to write directory")
	}

	return oid, nil
}

View on GitHub (pinned to 82495e54b5)