{"record":{"id":"b098a61d3f9850c0","repo":"dutchcoders/transfer.sh","slug":"could-not-encode-metadata","errorCode":null,"errorMessage":"could not encode metadata","messagePattern":"could not encode metadata","errorType":"http","errorClass":null,"httpStatus":404,"severity":"error","filePath":"server/handlers.go","lineNumber":897,"sourceCode":"\tif err != nil {\n\t\treturn metadata, err\n\t}\n\n\tif err := json.NewDecoder(r).Decode(&metadata); err != nil {\n\t\treturn metadata, err\n\t} else if metadata.MaxDownloads != -1 && metadata.Downloads >= metadata.MaxDownloads {\n\t\treturn metadata, errors.New(\"maxDownloads expired\")\n\t} else if !metadata.MaxDate.IsZero() && time.Now().After(metadata.MaxDate) {\n\t\treturn metadata, errors.New(\"maxDate expired\")\n\t} else if metadata.MaxDownloads != -1 && increaseDownload {\n\t\t// todo(nl5887): mutex?\n\n\t\t// update number of downloads\n\t\tmetadata.Downloads++\n\n\t\tbuffer := &bytes.Buffer{}\n\t\tif err := json.NewEncoder(buffer).Encode(metadata); err != nil {\n\t\t\treturn metadata, errors.New(\"could not encode metadata\")\n\t\t} else if err := s.storage.Put(ctx, token, fmt.Sprintf(\"%s.metadata\", filename), buffer, \"text/json\", uint64(buffer.Len())); err != nil {\n\t\t\treturn metadata, errors.New(\"could not save metadata\")\n\t\t}\n\t}\n\n\treturn metadata, nil\n}\n\nfunc (s *Server) checkDeletionToken(ctx context.Context, deletionToken, token, filename string) error {\n\ts.lock(token, filename)\n\tdefer s.unlock(token, filename)\n\n\tvar metadata metadata\n\n\tr, _, err := s.storage.Get(ctx, token, fmt.Sprintf(\"%s.metadata\", filename), nil)\n\tdefer storage.CloseCheck(r)\n\n\tif s.storage.IsNotExist(err) {","sourceCodeStart":879,"sourceCodeEnd":915,"githubUrl":"https://github.com/dutchcoders/transfer.sh/blob/c37bfd95797fd6da8a6da53fc13d191994b3f687/server/handlers.go#L879-L915","documentation":"After incrementing the download counter, checkMetadata re-serializes the metadata to JSON and persists it back to storage. If json.Encoder fails to encode the in-memory metadata struct, this error is returned and the download is aborted. It indicates the metadata struct cannot be marshaled (essentially a programming/serialization invariant failure, since the struct is normally JSON-safe).","triggerScenarios":"checkMetadata with increaseDownload=true on a file with a finite MaxDownloads where json.NewEncoder(buffer).Encode(metadata) returns an error — practically only when the metadata struct holds an unmarshalable value (e.g. invalid field types or a corrupted in-memory state).","commonSituations":"Custom builds that added non-serializable fields to the metadata struct; metadata types changed between versions such that freshly decoded values cannot be re-encoded; corrupted metadata round-trips.","solutions":["Inspect server logs for the underlying json error and check which metadata field fails to marshal.","Ensure the metadata struct only contains JSON-serializable fields (no channels, funcs, or unsupported types).","Re-upload the file to regenerate clean metadata.","Update/patch the server build if a version change altered the metadata schema; consider logging the raw error instead of discarding it."],"exampleFix":"// before\nif err := json.NewEncoder(buffer).Encode(metadata); err != nil {\n\treturn metadata, errors.New(\"could not encode metadata\")\n}\n// after\nif err := json.NewEncoder(buffer).Encode(metadata); err != nil {\n\treturn metadata, fmt.Errorf(\"could not encode metadata: %w\", err)\n}","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"could not encode metadata\") {\n\t// retry download without relying on counter update, or report server bug\n\treturn retryDownload()\n}","preventionTips":["Keep the metadata struct JSON-serializable when customizing the server.","Test metadata round-trips (encode/decode) in unit tests after schema changes.","Log the wrapped json error instead of discarding it."],"tags":["json","serialization","metadata","go"],"backgroundTag":"json-marshal-failed","analyzedSha":"c37bfd95797fd6da8a6da53fc13d191994b3f687","analyzedAt":"2026-09-05T10:21:07.548Z","contentChangedAt":"2026-09-05T10:21:07.548Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}