siyuan-note/siyuan · error

import task not found or expired

Error message

import task not found or expired

What it means

Returned by claimStagedSYImport (import.go:266) when the token passes format validation but the staged .zip file no longer exists at stagedSYImportPath(token). This happens when the staged import expired (cleanupStagedSYImports removes entries older than stagedSYImportTTL), was already claimed (claim renames it away), or was manually deleted.

Source

Thrown at kernel/api/import.go:266

		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 251596fc0d)

Solutions

  1. Re-stage the import (re-upload) to get a fresh token, then claim promptly within stagedSYImportTTL.
  2. Ensure the claim request fires immediately after a successful stage response.
  3. Guard against double-submit on the client (disable the confirm button after first click).
Defensive patterns

Strategy: retry

Validate before calling

// Re-stage if too much time elapsed (token likely expired)
if (Date.now() - stagedAt > TTL_MS) { token = await stageImport(data); }

Try / catch

try { await claimImport(token); }
catch (e) {
  if (/not found or expired/.test(e.msg)) { token = await stageImport(data); await claimImport(token); }
  else throw e;
}

Prevention

When it happens

Trigger: Issuing the claim/finalize request for an SY import whose staged artifact is gone: too much time elapsed between stage and claim (exceeded stagedSYImportTTL), the same token was claimed twice (the first claim renamed the file to '-importing.zip'), or the temp/import/sy dir was cleared by another process or kernel restart.

Common situations: User staged an import, got distracted, and finalized minutes/hours later. Network hiccup caused a double-submit of the claim. Temp directory cleanup/eviction. Container or ephemeral filesystem losing util.TempDir between requests.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/3138002623c06240. Report an issue: GitHub.