{"record":{"id":"e1c964007e5762a5","repo":"AlistGo/alist","slug":"not-implement","errorCode":null,"errorMessage":"not implement","messagePattern":"not implement","errorType":"exception","errorClass":"NotImplement","httpStatus":null,"severity":"warning","filePath":"internal/errs/errors.go","lineNumber":11,"sourceCode":"package errs\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\tpkgerr \"github.com/pkg/errors\"\n)\n\nvar (\n\tNotImplement = errors.New(\"not implement\")\n\tNotSupport   = errors.New(\"not support\")\n\tRelativePath = errors.New(\"access using relative path is not allowed\")\n\n\tMoveBetweenTwoStorages = errors.New(\"can't move files between two storages, try to copy\")\n\tUploadNotSupported     = errors.New(\"upload not supported\")\n\n\tMetaNotFound     = errors.New(\"meta not found\")\n\tStorageNotFound  = errors.New(\"storage not found\")\n\tStreamIncomplete = errors.New(\"upload/download stream incomplete, possible network issue\")\n\tStreamPeekFail   = errors.New(\"StreamPeekFail\")\n\n\tUnknownArchiveFormat      = errors.New(\"unknown archive format\")\n\tWrongArchivePassword      = errors.New(\"wrong archive password\")\n\tDriverExtractNotSupported = errors.New(\"driver extraction not supported\")\n)\n\n// NewErr wrap constant error with an extra message\n// use errors.Is(err1, StorageNotFound) to check if err belongs to any internal error","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/internal/errs/errors.go#L1-L29","documentation":"errs.NotImplement marks a driver method that the storage backend deliberately does not provide (as opposed to not-yet-written). When a caller invokes such a method on the driver, this sentinel is returned so upper layers can surface 'this operation is not available' rather than panic or silently no-op.","triggerScenarios":"Calling an optional driver operation that the specific driver never implemented — e.g. Rename, Move, Copy, Put, or driver-side archive extraction on a read-only or minimal driver whose method body is 'return errs.NotImplement'.","commonSituations":"UI showing actions (rename/move/upload) for a storage whose driver doesn't support them; automation assuming a uniform driver interface hits a minimal driver; new drivers where only List/Link exist; feature-gating code checking driver capabilities by error type.","solutions":["Check the driver's documented capability set before invoking optional operations","Guard the call: treat NotImplement as 'feature absent' and hide/disable the corresponding UI action","Switch to a driver that supports the operation, or perform the operation out-of-band","For driver authors: implement the method or keep returning the sentinel so callers can detect it"],"exampleFix":"// before\nerr := fsRename(ctx, storage, obj, \"new.txt\")\n\n// after\nerr := fsRename(ctx, storage, obj, \"new.txt\")\nif errors.Is(err, errs.NotImplement) {\n    // hide/disable rename in UI for this storage\n}","handlingStrategy":"type-guard","validationCode":"// consult driver capabilities before calling\nif !driverSupports(storage.Driver, \"Rename\") { return errs.NotImplement }","typeGuard":"func isNotImplement(err error) bool { return errors.Is(err, errs.NotImplement) }","tryCatchPattern":"err := fs.Rename(ctx, storage, obj, newName)\nif errors.Is(err, errs.NotImplement) {\n    hideActionInUI(\"rename\", storage) // degrade gracefully\n} else if err != nil { return err }","preventionTips":["Model per-driver capabilities and filter UI actions by them","Check for the sentinel with errors.Is, not string matching","Treat NotImplement as absent feature — don't retry"],"tags":["driver","capability","interface","go"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}