AlistGo/alist · error

server returns no url

Error message

server returns no url

What it means

CloudreveV4 Link() calls POST /file/url with the file path and download=true; the call succeeds but the response contains zero URLs. The server agreed to the request yet produced no downloadable link, so the driver cannot build a model.Link.

Source

Thrown at drivers/cloudreve_v4/driver.go:146

			},
			Thumbnail: thumb,
		}, nil
	})
}

func (d *CloudreveV4) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
	var url FileUrlResp
	err := d.request(http.MethodPost, "/file/url", func(req *resty.Request) {
		req.SetBody(base.Json{
			"uris":     []string{file.GetPath()},
			"download": true,
		})
	}, &url)
	if err != nil {
		return nil, err
	}
	if len(url.Urls) == 0 {
		return nil, errors.New("server returns no url")
	}
	exp := time.Until(url.Expires)
	return &model.Link{
		URL:        url.Urls[0].URL,
		Expiration: &exp,
	}, nil
}

func (d *CloudreveV4) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
	return d.request(http.MethodPost, "/file/create", func(req *resty.Request) {
		req.SetBody(base.Json{
			"type":              "folder",
			"uri":               parentDir.GetPath() + "/" + dirName,
			"error_on_conflict": true,
		})
	}, nil)
}

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Retry the download after refreshing the listing to confirm the file still exists.
  2. Check that the file's storage policy in Cloudrebve V4 allows direct download links.
  3. Test POST /file/url manually with the same body and inspect the full JSON to see why the list is empty.
  4. Update to the latest driver version if the V4 API shape changed (field names like uris/download).
Defensive patterns

Strategy: validation

Validate before calling

// guard before using the response
if len(url.Urls) == 0 {
    return nil, errors.New("server returns no url")
}
// caller-side: verify file still listed before requesting a link
if _, err := d.getFileInfo(ctx, file.GetPath()); err != nil {
    return nil, fmt.Errorf("file missing before link fetch: %w", err)
}

Type guard

func hasUsableUrl(r FileUrlResp) bool {
    return len(r.Urls) > 0 && r.Urls[0].URL != "" && time.Until(r.Expires) > 0
}

Try / catch

link, err := d.Link(ctx, file, args)
if err != nil {
    if err.Error() == "server returns no url" {
        // re-list the parent to refresh state, then retry once
        d.List(ctx, parent)
        link, err = d.Link(ctx, file, args)
    }
    if err != nil { return nil, err }
}

Prevention

When it happens

Trigger: Any download/link request (streaming a file, copying URL, preview) where url.Urls is empty. Occurs when the file's storage policy provides no direct link, the file is archived/recycled, or the V4 server returns an empty list for unsupported URI forms.

Common situations: File stored on a policy without direct-link support (e.g. server-proxied only); path passed with a leading/trailing form the server does not resolve; file deleted between listing and download; Cloudrebve V4 build where /file/url requires different body fields.

Related errors


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