AlistGo/alist · error

s3 transition task manager is not initialized

Error message

s3 transition task manager is not initialized

What it means

Returned by internal/fs/other.go when an fs 'other' request targets an S3 storage with method 'archive' or 'thaw' (S3 Glacier transition) but the package-level S3TransitionTaskManager is still nil. The manager is a tache task manager initialized during bootstrap (internal/bootstrap/task.go:44); the check guards against submitting tasks before that init has run.

Source

Thrown at internal/fs/other.go:67

	storage, actualPath, err := op.GetStorageAndActualPath(path)
	if err != nil {
		return errors.WithMessage(err, "failed get storage")
	}
	return op.Remove(ctx, storage, actualPath)
}

func other(ctx context.Context, args model.FsOtherArgs) (interface{}, error) {
	storage, actualPath, err := op.GetStorageAndActualPath(args.Path)
	if err != nil {
		return nil, errors.WithMessage(err, "failed get storage")
	}
	originalPath := args.Path

	if _, ok := storage.(*s3.S3); ok {
		method := strings.ToLower(strings.TrimSpace(args.Method))
		if method == s3.OtherMethodArchive || method == s3.OtherMethodThaw {
			if S3TransitionTaskManager == nil {
				return nil, errors.New("s3 transition task manager is not initialized")
			}
			var payload json.RawMessage
			if args.Data != nil {
				raw, err := json.Marshal(args.Data)
				if err != nil {
					return nil, errors.WithMessage(err, "failed to encode request payload")
				}
				payload = raw
			}
			taskCreator, _ := ctx.Value("user").(*model.User)
			tsk := &S3TransitionTask{
				TaskExtension:    task.TaskExtension{Creator: taskCreator},
				status:           "queued",
				StorageMountPath: storage.GetStorage().MountPath,
				ObjectPath:       actualPath,
				DisplayPath:      originalPath,
				ObjectName:       stdpath.Base(actualPath),
				Transition:       method,

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Ensure the full bootstrap sequence (including internal/bootstrap/task.go) runs before serving requests or invoking fs.Other
  2. In tests/embedding, initialize fs.S3TransitionTaskManager with tache.NewManager the same way bootstrap does
  3. If seen in production, check startup logs for bootstrap panics that aborted initialization

Example fix

// before
res, err := fs.Other(ctx, args) // S3TransitionTaskManager may be nil in tests

// after
fs.S3TransitionTaskManager = tache.NewManager[*fs.S3TransitionTask](func(t *fs.S3TransitionTask) error { return t.Run() })
res, err := fs.Other(ctx, args)
Defensive patterns

Strategy: validation

Validate before calling

// ensure bootstrap task init ran before handling S3 other-methods
if fs.S3TransitionTaskManager == nil {
    return errors.New("task system not ready; finish bootstrap first")
}

Type guard

func s3TransitionReady() bool {
    return fs.S3TransitionTaskManager != nil
}

Try / catch

res, err := fs.Other(ctx, args)
if err != nil && strings.Contains(err.Error(), "not initialized") {
    // re-run bootstrap or defer the request; not a client error
}

Prevention

When it happens

Trigger: Calling the /api/fs/other endpoint with method=archive|thaw on an S3-mounted path before bootstrap completed, or from code paths (tests, early startup hooks, embedded usage) that link internal/fs without running the bootstrap sequence that assigns fs.S3TransitionTaskManager.

Common situations: Unit tests or tooling importing internal/fs directly and calling other() without bootstrap; a race during process startup where HTTP serving begins before task managers register; custom builds that skip the task bootstrap step. In a normally started server it should never fire.

Related errors


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