{"record":{"id":"b5859740f6bd7b2e","repo":"kopia/kopia","slug":"unable-to-encode-directory-json","errorCode":null,"errorMessage":"unable to encode directory JSON","messagePattern":"unable to encode directory JSON","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"snapshot/snapshotfs/dir_writer.go","lineNumber":27,"sourceCode":"\t\"github.com/kopia/kopia/repo\"\n\t\"github.com/kopia/kopia/repo/compression\"\n\t\"github.com/kopia/kopia/repo/object\"\n\t\"github.com/kopia/kopia/snapshot\"\n)\n\n// WriteDirManifest writes a directory manifest to the repository and returns the object ID.\nfunc WriteDirManifest(ctx context.Context, rep repo.RepositoryWriter, dirRelativePath string, dirManifest *snapshot.DirManifest, metadataComp compression.Name) (object.ID, error) {\n\twriter := rep.NewObjectWriter(ctx, object.WriterOptions{\n\t\tDescription:        \"DIR:\" + dirRelativePath,\n\t\tPrefix:             objectIDPrefixDirectory,\n\t\tCompressor:         metadataComp,\n\t\tMetadataCompressor: metadataComp,\n\t})\n\n\tdefer writer.Close() //nolint:errcheck\n\n\tif err := json.NewEncoder(writer).Encode(dirManifest); err != nil {\n\t\treturn object.EmptyID, errors.Wrap(err, \"unable to encode directory JSON\")\n\t}\n\n\toid, err := writer.Result()\n\tif err != nil {\n\t\treturn object.EmptyID, errors.Wrap(err, \"unable to write directory\")\n\t}\n\n\treturn oid, nil\n}\n","sourceCodeStart":9,"sourceCodeEnd":37,"githubUrl":"https://github.com/kopia/kopia/blob/82495e54b584c1ef6073c9e1be048f57f8aef078/snapshot/snapshotfs/dir_writer.go#L9-L37","documentation":"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.","triggerScenarios":"json.NewEncoder(writer).Encode(dirManifest) returns an error inside WriteDirManifest — the DirManifest struct failed to serialize before being uploaded as a directory object.","commonSituations":"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.","solutions":["Check the inner wrapped error; if it is an io.Writer error, treat it as an object-write/storage problem and check repository health.","Ensure DirManifestBuilder was populated with valid DirEntry values (no nil pointers or corrupt ObjectIDs).","Upgrade Kopia if a built-in type fails to marshal — for standard structs this indicates a bug.","Retry the write after resolving any transient storage issues; content-addressed writes are safe to retry."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if len(dirManifest.Entries) == 0 && !allowEmpty { return errors.New(\"refusing to write empty dir manifest\") }","typeGuard":"func writableManifest(dm snapshot.DirManifest) bool {\n    for _, e := range dm.Entries {\n        if e == nil || e.ObjectID == \"\" { return false }\n    }\n    return true\n}","tryCatchPattern":"oid, err := snapshotfs.WriteDirManifest(ctx, rep, prevOID, dm, comp)\nif err != nil {\n    if strings.Contains(err.Error(), \"unable to encode directory JSON\") {\n        log.Printf(\"manifest encoding failed: %+v\", err)\n    }\n    return object.EmptyID, err\n}","preventionTips":["Populate DirManifestBuilder only with fully valid DirEntry values.","Upgrade Kopia if built-in manifest types fail to serialize (library bug).","Check object-writer health; encoder errors often mask storage write failures.","Keep directory entry counts reasonable; split pathological trees before rewriting."],"tags":["kopia","json","manifest","encoding"],"backgroundTag":"json-marshal-failed","analyzedSha":"82495e54b584c1ef6073c9e1be048f57f8aef078","analyzedAt":"2026-09-07T20:35:21.689Z","contentChangedAt":"2026-09-07T20:35:21.689Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}