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

  1. Re-stage/re-upload the .sy zip and use the new token immediately.
  2. Check the staging directory (temp/import) for the file before claiming.
  3. Implement claim idempotency on the client: treat 'not found or expired' as needing a fresh upload, not a retry with the same token.
  4. 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

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


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")) {
			continue

View on GitHub (pinned to 9f775e8a12)