{"record":{"id":"278b3f1fec15a994","repo":"AlistGo/alist","slug":"not-support","errorCode":null,"errorMessage":"not support","messagePattern":"not support","errorType":"exception","errorClass":"NotSupport","httpStatus":null,"severity":"warning","filePath":"internal/errs/errors.go","lineNumber":12,"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\nfunc NewErr(err error, format string, a ...any) error {","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/internal/errs/errors.go#L1-L30","documentation":"errs.NotSupport is distinct from NotImplement: it marks operations the backend fundamentally does not support (the provider API offers no equivalent), not merely unimplemented code. It lets upper layers differentiate 'will never work' from 'not built yet'.","triggerScenarios":"Calling an operation the provider cannot do — e.g. Move on a driver whose remote API has no move endpoint, upload to a write-protected backend, or a link-type the account tier disallows — where the driver explicitly returns errs.NotSupport.","commonSituations":"Users attempting move/copy/upload on read-only or link-based storages; frontends not filtering actions by driver capability; version upgrades reclassifying operations from supported to unsupported due to API changes.","solutions":["Verify the operation is possible on the provider at all (check its API docs) before wiring UI/automation","Handle NotSupport explicitly and hide or disable the action for that storage type","Use copy+delete as a substitute for unsupported move where the driver supports both","Pick a different storage backend if the operation is a hard requirement"],"exampleFix":"// before\nerr := d.Move(ctx, src, dst)\nif err != nil { return err }\n\n// after\nerr := d.Move(ctx, src, dst)\nif errors.Is(err, errs.NotSupport) {\n    err = copyThenDelete(ctx, src, dst) // fallback strategy\n}","handlingStrategy":"fallback","validationCode":"if !driverSupports(storage.Driver, \"Move\") { return errs.NotSupport }","typeGuard":"func isNotSupport(err error) bool { return errors.Is(err, errs.NotSupport) }","tryCatchPattern":"err := d.Move(ctx, src, dst)\nif errors.Is(err, errs.NotSupport) {\n    err = copyThenDelete(ctx, src, dst) // documented fallback for move\n}","preventionTips":["Differentiate NotSupport (impossible) from NotImplement (unbuilt) in handling","Hide fundamentally unsupported actions rather than erroring at click time","Where move is unsupported, offer copy+delete flows explicitly"],"tags":["driver","capability","unsupported-operation","go"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}