AlistGo/alist · error

missing file path and id

Error message

missing file path and id

What it means

openDownloadURL builds the MCP.getDownLoadUrl Open-API call from either fpath or nid. If the object has neither a path nor an ID, there is nothing to sign the request with and the guard fires (drivers/yunpan360/util.go:697).

Source

Thrown at drivers/yunpan360/util.go:697

	if err != nil {
		return nil, err
	}
	return &resp, nil
}

func (d *Yunpan360) openDownloadURL(ctx context.Context, file model.Obj) (*OpenDownloadResp, error) {
	var resp OpenDownloadResp
	signParams := map[string]string{}
	body := map[string]string{}

	if file.GetPath() != "" {
		signParams["fpath"] = normalizeRemotePath(file.GetPath())
		body["fpath"] = signParams["fpath"]
	} else if file.GetID() != "" {
		signParams["nid"] = file.GetID()
		body["nid"] = file.GetID()
	} else {
		return nil, errors.New("missing file path and id")
	}

	err := d.openPOST(ctx, "MCP.getDownLoadUrl", signParams, nil, body, &resp, true)
	if err != nil {
		return nil, err
	}
	return &resp, nil
}

func (d *Yunpan360) cookieMakeDir(ctx context.Context, fullPath string) (*CookieMkdirResp, error) {
	var resp CookieMkdirResp
	body := map[string]string{
		"path":      ensureDirAPIPath(fullPath),
		"owner_qid": "0",
	}
	err := d.cookieRequestForm(ctx, "/file/mkdir", body, &resp)
	if err != nil {
		return nil, err

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Pass an object returned by List() — it always has path or nid populated
  2. If building objects manually, set at least one of Path or ID (ID preferred)
  3. Guard against download attempts on the root/directory objects in caller code

Example fix

// before
_, err := d.openDownloadURL(ctx, &model.Object{})

// after
_, err := d.openDownloadURL(ctx, &model.Object{Path: "/docs/a.txt", ID: "123456789"})
Defensive patterns

Strategy: validation

Validate before calling

if file.GetPath() == "" && file.GetID() == "" { return errors.New("object needs path or id") }

Type guard

func identifiable(obj model.Obj) bool { return obj.GetPath() != "" || obj.GetID() != "" }

Try / catch

if !identifiable(file) { return nil, errors.New("re-list to obtain path/nid") }
return d.openDownloadURL(ctx, file)

Prevention

When it happens

Trigger: Calling the Open-API download path with a model.Obj whose GetPath() and GetID() are both empty. Happens with zero-value objects, root placeholders, or objects stripped by serialization before Link().

Common situations: Caller constructs model.Object{} without fields; object fields lost across JSON boundaries (omitempty dropping empty strings is fine here — the source never set them); passing the storage root ("/", empty id) to a file download call.

Related errors


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