AlistGo/alist · error

can't convert obj to URL

Error message

can't convert obj to URL

What it means

Teambition's Link() only supports objects that implement model.URL (objects that already carry a direct download URL). It does a Go interface type assertion file.(model.URL); if the obj is a plain model.Object without a URL method, the assertion fails and Link returns this error instead of a link. There is no fallback API call to fetch a URL on demand.

Source

Thrown at drivers/teambition/driver.go:50

func (d *Teambition) Drop(ctx context.Context) error {
	return nil
}

func (d *Teambition) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
	return d.getFiles(dir.GetID())
}

func (d *Teambition) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
	if u, ok := file.(model.URL); ok {
		url := u.URL()
		res, _ := base.NoRedirectClient.R().Get(url)
		if res.StatusCode() == 302 {
			url = res.Header().Get("location")
		}
		return &model.Link{URL: url}, nil
	}
	return nil, errors.New("can't convert obj to URL")
}

func (d *Teambition) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
	data := base.Json{
		"objectType":     "collection",
		"_projectId":     d.ProjectID,
		"_creatorId":     "",
		"created":        "",
		"updated":        "",
		"title":          dirName,
		"color":          "blue",
		"description":    "",
		"workCount":      0,
		"collectionType": "",
		"recentWorks":    []interface{}{},
		"_parentId":      parentDir.GetID(),
		"subCount":       nil,
	}

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Pass the original object instance returned by getFiles()/List(), preserving its concrete type
  2. Disable or clear the metadata cache for this storage if it is downcasting objects
  3. Update the driver — newer versions attach URLs at List time so the assertion holds

Example fix

// before
var file model.Obj = &model.Object{Name: "doc.pdf"}
link, err := d.Link(ctx, file, args) // -> "can't convert obj to URL"

// after
files, _ := d.List(ctx, dir, model.ListArgs{})
var file model.Obj
for _, f := range files { if f.GetName() == "doc.pdf" { file = f } }
link, err := d.Link(ctx, file, args)
Defensive patterns

Strategy: type-guard

Validate before calling

// before calling Link, ensure the object carries a URL
if _, ok := file.(model.URL); !ok {
    return fmt.Errorf("object %q cannot be linked directly; re-list to obtain a URL-capable object", file.GetName())
}

Type guard

func isURLCarrier(o model.Obj) bool {
    _, ok := o.(model.URL)
    return ok
}

Try / catch

link, err := d.Link(ctx, file, args)
if err != nil && strings.Contains(err.Error(), "can't convert obj to URL") {
    objs, _ := d.List(ctx, parentDir, model.ListArgs{})
    for _, o := range objs {
        if o.GetName() == file.GetName() {
            if _, ok := o.(model.URL); ok {
                link, err = d.Link(ctx, o, args)
            }
        }
    }
}

Prevention

When it happens

Trigger: Calling Link() on a Teambition file object that was constructed as a generic model.Object rather than the driver's URL-carrying object type (e.g. from a cache layer that rebuilt objects, or a custom caller synthesizing objects).

Common situations: Metadata cache re-serializing objects and losing the original type; Custom integrations calling Link with objects from List() of a different driver; Driver versions where only some object kinds (uploaded files vs. collections) implement model.URL

Related errors


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