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
- Pass the original object instance returned by getFiles()/List(), preserving its concrete type
- Disable or clear the metadata cache for this storage if it is downcasting objects
- 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
- Never rebuild Teambition objects across serialization boundaries — pass originals
- Check the type assertion before calling Link on uncertain objects
- Keep driver and metadata cache versions in sync so URL-carrying types survive
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
- unable to convert file to Object
- missing cookie or qrcode account
- get download url failed: {string(res)}
- chunk part has no readable link
- server returns no url
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/765801878ffa685a.
Report an issue: GitHub.