AlistGo/alist · error

unable to convert file to Object

Error message

unable to convert file to Object

What it means

The Wopan driver's Link method expects the incoming model.Obj to be the driver's concrete *Object type (carrying FID). If it receives any other Obj implementation (a generic model.Object, a wrapped/cached object, or an object reconstructed by an upper layer), the type assertion fails and Link returns 'unable to convert file to Object'.

Source

Thrown at drivers/wopan/driver.go:87

		}
		pageNum++
	}
	return res, nil
}

func (d *Wopan) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
	if f, ok := file.(*Object); ok {
		res, err := d.client.GetDownloadUrlV2([]string{f.FID}, func(req *resty.Request) {
			req.SetContext(ctx)
		})
		if err != nil {
			return nil, err
		}
		return &model.Link{
			URL: res.List[0].DownloadUrl,
		}, nil
	}
	return nil, fmt.Errorf("unable to convert file to Object")
}

func (d *Wopan) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
	familyID := d.FamilyID
	if familyID == "" {
		familyID = d.defaultFamilyID
	}
	_, err := d.client.CreateDirectory(d.getSpaceType(), parentDir.GetID(), dirName, familyID, func(req *resty.Request) {
		req.SetContext(ctx)
	})
	return err
}

func (d *Wopan) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
	dirList := make([]string, 0)
	fileList := make([]string, 0)
	if srcObj.IsDir() {
		dirList = append(dirList, srcObj.GetID())

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Ensure objects passed to Link come from the Wopan driver's own List/Get so they are *Object.
  2. Clear the path cache and retry so objects are re-fetched from the driver.
  3. If writing custom code against model.Obj, fetch the object via the storage's Get(path) before calling Link.

Example fix

// before
obj := model.Object{Path: "/f.txt"}      // generic object
link, err := d.Link(ctx, obj, args)      // -> conversion error

// after
obj, err := d.Get(ctx, "/f.txt")        // returns *Object
link, err := d.Link(ctx, obj, args)
Defensive patterns

Strategy: type-guard

Type guard

func isWopanObject(o model.Obj) bool {
    _, ok := o.(*driver.Object) // drivers/wopan Object
    return ok
}

Try / catch

obj, err := d.Get(ctx, path)
if err != nil { return err }
if _, ok := obj.(*Object); !ok {
    // stale cache/generic object: force refresh via List before Link
    return fmt.Errorf("refresh object via driver Get before Link")
}
link, err := d.Link(ctx, obj, args)

Prevention

When it happens

Trigger: Calling Link with an object not created by the Wopan driver's own List — e.g. after path caching reconstructs plain model.Object values, or code passes model.NewObj or merges objects from another driver.

Common situations: Meta/path-cache layers or copy tasks that re-create objects generically, third-party code driving the fs API directly, or version changes where the cache stopped preserving driver object types.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/1e95838f4aecf2cd. Report an issue: GitHub.