AlistGo/alist · error

missing file id

Error message

missing file id

What it means

A guard in cookieDownloadURLOnce: building a download URL in cookie mode requires the file's nid (360's numeric id). If model.Obj.GetID() is empty or whitespace, the request cannot be formed and this error returns immediately (drivers/yunpan360/util.go:344).

Source

Thrown at drivers/yunpan360/util.go:344

		merged[key] = value
	}
	return merged
}

func (d *Yunpan360) cookieDownloadURL(ctx context.Context, file model.Obj) (*CookieDownloadResp, error) {
	resp, err := d.cookieDownloadURLOnce(ctx, file, false)
	if err == nil {
		return resp, nil
	}

	d.invalidateCookieDownloadSession()
	return d.cookieDownloadURLOnce(ctx, file, true)
}

func (d *Yunpan360) cookieDownloadURLOnce(ctx context.Context, file model.Obj, refresh bool) (*CookieDownloadResp, error) {
	nid := strings.TrimSpace(file.GetID())
	if nid == "" {
		return nil, errors.New("missing file id")
	}

	fname := normalizeRemotePath(file.GetPath())
	if fname == "" {
		return nil, errors.New("missing file path")
	}

	ownerQID, token, err := d.resolveCookieDownloadParams(ctx, file, refresh)
	if err != nil {
		return nil, err
	}

	var resp CookieDownloadResp
	err = d.cookieRequestForm(ctx, downloadPath, map[string]string{
		"nid":       nid,
		"fname":     fname,
		"owner_qid": ownerQID,
		"token":     token,

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Ensure the object passed to download comes from a real driver List() result, not a hand-built struct
  2. Set the ID field from the listing's nid before requesting a download link
  3. Verify callers are not passing directories to file-download APIs
  4. If mapping objects between layers, copy the ID field explicitly

Example fix

// before
file := &model.Object{Path: "/docs/a.txt"} // no ID
link, err := d.Link(ctx, file, model.LinkArgs{})

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

Strategy: validation

Validate before calling

if strings.TrimSpace(file.GetID()) == "" { return errors.New("refusing download: object has no ID") }

Type guard

func hasFileID(obj model.Obj) bool { return strings.TrimSpace(obj.GetID()) != "" }

Try / catch

if !hasFileID(file) {
    file = refreshFromList(ctx, file) // re-list parent, match by path
}
resp, err := d.cookieDownloadURL(ctx, file)
if err != nil { return nil, err }

Prevention

When it happens

Trigger: Calling the driver's link/download path with an object that has no ID set — e.g. a synthetic model.Obj constructed by caller code, an object built only from a path (root dir placeholder), or an object whose ID was lost during conversion/mapping before download.

Common situations: Custom code creates model.Obj implementations (e.g. model.Object with only Path set) and passes them to a download API; a directory object (dirs often have no usable nid for download) is passed to a file-download call; upcasting/copy bugs strip the ID field.

Related errors


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