{"record":{"id":"422fd8ca9c5d43c6","repo":"AlistGo/alist","slug":"unable-to-convert-dir-to-mega-n","errorCode":null,"errorMessage":"unable to convert dir to mega n","messagePattern":"unable to convert dir to mega n","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/mega/driver.go","lineNumber":78,"sourceCode":"\t\tfor i := range nodes {\n\t\t\tn := nodes[i]\n\t\t\tif n.GetType() != mega.FILE && n.GetType() != mega.FOLDER {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif _, ok := fn[n.GetName()]; !ok {\n\t\t\t\tfn[n.GetName()] = &MegaNode{n}\n\t\t\t} else if sameNameObj := fn[n.GetName()]; (&MegaNode{n}).ModTime().After(sameNameObj.ModTime()) {\n\t\t\t\tfn[n.GetName()] = &MegaNode{n}\n\t\t\t}\n\t\t}\n\t\tres := make([]model.Obj, 0)\n\t\tfor _, v := range fn {\n\t\t\tres = append(res, v)\n\t\t}\n\t\treturn res, nil\n\t}\n\tlog.Errorf(\"can't convert: %+v\", dir)\n\treturn nil, fmt.Errorf(\"unable to convert dir to mega n\")\n}\n\nfunc (d *Mega) GetRoot(ctx context.Context) (model.Obj, error) {\n\tn := d.c.FS.GetRoot()\n\tlog.Debugf(\"mega root: %+v\", *n)\n\treturn &MegaNode{n}, nil\n}\n\nfunc (d *Mega) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {\n\tif node, ok := file.(*MegaNode); ok {\n\n\t\t//down, err := d.c.NewDownload(n.Node)\n\t\t//if err != nil {\n\t\t//\treturn nil, fmt.Errorf(\"open download file failed: %w\", err)\n\t\t//}\n\n\t\tsize := file.GetSize()\n\t\tresultRangeReader := func(ctx context.Context, httpRange http_range.Range) (io.ReadCloser, error) {","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/mega/driver.go#L60-L96","documentation":"Mega driver List was called with a dir that is not the driver's *MegaNode concrete type, so the children cannot be enumerated. The preceding log line ('can't convert: %+v') dumps the offending object. Root cause is the same class as the other Mega conversion errors: the model.Obj came from outside this driver's own object graph.","triggerScenarios":"Listing a directory object fabricated by another layer (path-based virtual object, mock, or cross-driver reference); passing model.Object value instead of *MegaNode; objects reconstructed after serialization between listing and listing a subfolder.","commonSituations":"File-manager frameworks that build virtual directory trees from paths; tests with generic fake objects; state restored from persistence losing the concrete node type.","solutions":["Always obtain the dir from d.GetRoot() or a previous List result of the same driver instance","Use GetRoot()+path resolution through the driver itself instead of synthesizing objects","In frameworks, route through driver.Get(path) to re-materialize a *MegaNode before List","For tests, wrap real mega nodes: construct MegaNode{n} from d.c.FS.Get(...)"],"exampleFix":"// before\nif node, ok := dir.(*MegaNode); ok {\n    /* list children */\n}\nlog.Errorf(\"can't convert: %+v\", dir)\nreturn nil, fmt.Errorf(\"unable to convert dir to mega n\")\n\n// after (fail fast with actionable info)\nnode, ok := dir.(*MegaNode)\nif !ok {\n    log.Errorf(\"can't convert dir (type %T) to *MegaNode; re-fetch via Get(path)\", dir)\n    return nil, fmt.Errorf(\"unable to convert dir to mega n (got %T)\", dir)\n}","handlingStrategy":"type-guard","validationCode":"// Resolve dirs through the driver itself\nnode, ok := dir.(*MegaNode)\nif !ok {\n    resolved, err := d.Get(ctx, dir.GetPath())\n    if err != nil { return nil, err }\n    node, ok = resolved.(*MegaNode)\n    if !ok { return nil, fmt.Errorf(\"unresolvable dir type %T\", dir) }\n}","typeGuard":"func isMegaNode(o model.Obj) bool {\n    _, ok := o.(*MegaNode)\n    return ok\n}","tryCatchPattern":"// Guard first; only call List with verified nodes\nif !isMegaNode(dir) {\n    dir, err = d.Get(ctx, dir.GetPath())\n    if err != nil { return nil, err }\n}\nreturn d.List(ctx, dir, args)","preventionTips":["Never synthesize dir objects; use GetRoot()/List() results","Route path-based access through driver.Get to re-materialize nodes","Check the driver's own log line ('can't convert') for the offending type"],"tags":["mega","type-assertion","driver","go"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}