siyuan-note/siyuan · warning
import task not found or expired
Error message
import task not found or expired
What it means
claimStagedSYImport looks up the staged zip at stagedSYImportPath(token); staged imports expire (cleanupStagedSYImports removes old ones). If the file no longer exists the function converts the os.Stat not-exist error into 'import task not found or expired', telling the caller to re-upload.
Solutions
- Re-stage/re-upload the .sy zip and use the new token immediately.
- Check the staging directory (temp/import) for the file before claiming.
- Implement claim idempotency on the client: treat 'not found or expired' as needing a fresh upload, not a retry with the same token.
- Increase/verify the staging retention window if imports legitimately take long before claiming.
Example fix
// before
await claim(oldToken) // expired after restart
// after
try { await claim(token) }
catch (e) {
if (String(e.msg).includes("not found or expired")) {
token = await stage(uploadFile); await claim(token)
}
} Defensive patterns
Strategy: retry
Validate before calling
const staged = await stat(join(tempDir, "import", token + ".zip")); if (!staged) await restage()
Try / catch
try { await claim(token) }
catch (e) { if (e.message === "import task not found or expired") { const t = await stage(file); await claim(t) } else throw e } Prevention
- Claim promptly after staging; do not leave staged imports idle
- Treat claim as one-shot; never reuse a token after a successful claim
- Re-stage after kernel restarts since temp staging is volatile
When it happens
Trigger: Claiming a token whose staged zip was already claimed (renamed away), deleted by cleanupStagedSYImports due to age, or removed by a kernel restart clearing the temp staging dir.
Common situations: User takes too long between upload and claim; double-submit of the claim request; kernel restarted between staging and claiming; temp dir cleaned by the OS.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- check data.zip failed
- copy data failed
- inspect imported notebook
- Obsidian Vault is unreadable
- read imported notebook conf
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/3138002623c06240.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/api/import.go:235
if statErr != nil {
return "", statErr
}
}
err = os.Rename(srcPath, stagedSYImportPath(token))
return
}
func claimStagedSYImport(token string) (path string, err error) {
if !isValidSYImportToken(token) {
return "", errors.New("invalid import token")
}
stagedSYImportLock.Lock()
defer stagedSYImportLock.Unlock()
cleanupStagedSYImports()
srcPath := stagedSYImportPath(token)
if _, err = os.Stat(srcPath); err != nil {
if os.IsNotExist(err) {
err = errors.New("import task not found or expired")
}
return "", err
}
path = filepath.Join(stagedSYImportDir(), token+"-importing.zip")
err = os.Rename(srcPath, path)
return
}
func cleanupStagedSYImports() {
entries, err := os.ReadDir(stagedSYImportDir())
if err != nil {
return
}
now := time.Now()
for _, entry := range entries {
name := entry.Name()
if !strings.HasSuffix(name, ".zip") || !isValidSYImportToken(strings.TrimSuffix(name, ".zip")) {
continueView on GitHub (pinned to 9f775e8a12)