{"record":{"id":"d29554da28ebf308","repo":"AlistGo/alist","slug":"missing-object-id","errorCode":null,"errorMessage":"missing object id","messagePattern":"missing object id","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/yunpan360/util.go","lineNumber":377,"sourceCode":"\t\t\"nid\":       nid,\n\t\t\"fname\":     fname,\n\t\t\"owner_qid\": ownerQID,\n\t\t\"token\":     token,\n\t}, &resp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &resp, nil\n}\n\nfunc (d *Yunpan360) cookieRename(ctx context.Context, srcObj model.Obj, newName string) error {\n\tpath := normalizeRemotePath(srcObj.GetPath())\n\tif path == \"\" {\n\t\treturn errors.New(\"missing object path\")\n\t}\n\tnid := strings.TrimSpace(srcObj.GetID())\n\tif nid == \"\" {\n\t\treturn errors.New(\"missing object id\")\n\t}\n\n\townerQID, err := d.resolveCookieOwnerQID(ctx, srcObj, false)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn d.cookieRequestForm(ctx, \"/file/rename\", map[string]string{\n\t\t\"path\":      path,\n\t\t\"nid\":       nid,\n\t\t\"newpath\":   strings.TrimSuffix(strings.TrimSpace(newName), \"/\"),\n\t\t\"owner_qid\": ownerQID,\n\t}, nil)\n}\n\nfunc (d *Yunpan360) resolveCookieDownloadParams(ctx context.Context, file model.Obj, refresh bool) (string, string, error) {\n\townerQID := sanitizeOwnerQID(d.OwnerQID)\n\ttoken := strings.TrimSpace(d.DownloadToken)","sourceCodeStart":359,"sourceCodeEnd":395,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/yunpan360/util.go#L359-L395","documentation":"Guard in cookieRename: the /file/rename form requires nid, so the source object must carry a non-empty ID. If srcObj.GetID() is blank, the rename is rejected (drivers/yunpan360/util.go:377).","triggerScenarios":"Renaming an object that has Path but no ID — e.g. a synthetic root folder object, or an object built by caller code that only filled Path/Name.","commonSituations":"Root directory objects (no nid) passed to rename; object created from a path string without listing; ID lost in a struct copy or JSON marshal/unmarshal.","solutions":["Use objects returned by the driver's List (they always carry nid)","If building objects manually, set ID from the listing that produced the path","Refuse rename operations on the root \"/\" object in caller code"],"exampleFix":"// before\nerr := d.Rename(ctx, &model.Object{Path: \"/docs/old.txt\"}, \"new.txt\")\n\n// after\nobj := &model.Object{Path: \"/docs/old.txt\", ID: \"888000111\", Name: \"old.txt\"}\nerr := d.Rename(ctx, obj, \"new.txt\")","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(srcObj.GetID()) == \"\" { return errors.New(\"cannot rename: object id missing\") }","typeGuard":"func hasObjectID(obj model.Obj) bool { return strings.TrimSpace(obj.GetID()) != \"\" }","tryCatchPattern":"if !hasObjectID(srcObj) { srcObj = relistParentFor(srcObj) }\nreturn d.cookieRename(ctx, srcObj, newName)","preventionTips":["Root objects have no nid — block rename on them upstream","Copy ID field explicitly in any object-mapping code","Prefer driver List() output over reconstructed objects"],"tags":["yunpan360","validation","rename","go"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}