AlistGo/alist · warning
cannot download a submodule
Error message
cannot download a submodule
What it means
Link() refuses to produce a download link when the fetched object's type is 'submodule': a git submodule entry points at a commit SHA in another repository, and the GitHub contents/raw API cannot serve it as a file. The driver surfaces this as an explicit, user-facing restriction instead of returning a broken URL.
Source
Thrown at drivers/github/driver.go:174
return ret, nil
} else {
ret := make([]model.Obj, 0, len(obj.Entries))
for _, entry := range obj.Entries {
if entry.Name != ".gitkeep" {
ret = append(ret, entry.toModelObj())
}
}
return ret, nil
}
}
func (d *Github) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
obj, err := d.get(file.GetPath())
if err != nil {
return nil, err
}
if obj.Type == "submodule" {
return nil, errors.New("cannot download a submodule")
}
url := obj.DownloadURL
ghProxy := strings.TrimSpace(d.Addition.GitHubProxy)
if ghProxy != "" {
url = strings.Replace(url, "https://raw.githubusercontent.com", ghProxy, 1)
}
return &model.Link{
URL: url,
}, nil
}
func (d *Github) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
if !d.isOnBranch {
return errors.New("cannot write to non-branch reference")
}
d.commitMutex.Lock()
defer d.commitMutex.Unlock()
parent, err := d.get(parentDir.GetPath())View on GitHub (pinned to 843d9dc814)
Solutions
- Do not download submodule entries through this mount; clone the repo with 'git clone --recurse-submodules' instead.
- If submodules are noise, ignore them in listings or hide them with the driver/front-end filter options.
- There is no driver-side fix — the raw API genuinely has no blob for a submodule pointer.
Defensive patterns
Strategy: type-guard
Validate before calling
obj, err := d.get(file.GetPath())
if err != nil { return nil, err }
if obj.Type == "submodule" {
return nil, errors.New("cannot download a submodule")
} Type guard
func isSubmodule(obj *TreeObj) bool {
return obj != nil && obj.Type == "submodule"
} Try / catch
link, err := d.Link(ctx, file, args)
if err != nil && err.Error() == "cannot download a submodule" {
// skip in UI / guide user to git clone --recurse-submodules
} Prevention
- Mark submodule entries as non-downloadable in listings.
- Use git clone --recurse-submodules for submodule content.
- Educate users that submodules are pointers, not blobs.
When it happens
Trigger: Clicking/downloading a directory entry whose tree type is 'submodule' (a .gitmodules entry) in a mounted GitHub repo. drivers/github/driver.go:174.
Common situations: Repos vendoring dependencies as submodules (common in C/C++ projects); users browsing a repo through OpenList and trying to download the submodule folder like a normal directory.
Related errors
- server returns no url
- empty download url
- cannot move a submodule
- cannot rename a submodule
- missing cookie or qrcode account
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/c20c13720b6f758a.
Report an issue: GitHub.