{"record":{"id":"1f16e692772562e4","repo":"kopia/kopia","slug":"unable-to-process-directory-q","errorCode":null,"errorMessage":"unable to process directory %q","messagePattern":"unable to process directory %q","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"snapshot/upload/upload.go","lineNumber":898,"sourceCode":"\n\t\tchildTree := policyTree.Child(entry.Name())\n\t\tchildPrevDirs := uniqueChildDirectories(ctx, prevDirs, entry.Name())\n\n\t\tde, err := uploadDirInternal(ctx, u, entry, childTree, childPrevDirs, childLocalDirPathOrEmpty, entryRelativePath, childDirBuilder, parentCheckpointRegistry)\n\t\tif errors.Is(err, errCanceled) {\n\t\t\treturn err\n\t\t}\n\n\t\tif err != nil {\n\t\t\t// Note: This only catches errors in subdirectories of the snapshot root, not on the snapshot\n\t\t\t// root itself. The intention is to always fail if the top level directory can't be read,\n\t\t\t// otherwise a meaningless, empty snapshot is created that can't be restored.\n\t\t\tvar dre dirReadError\n\t\t\tif errors.As(err, &dre) {\n\t\t\t\tisIgnoredError := childTree.EffectivePolicy().ErrorHandlingPolicy.IgnoreDirectoryErrors.OrDefault(false)\n\t\t\t\tu.reportErrorAndMaybeCancel(dre.error, isIgnoredError, parentDirBuilder, entryRelativePath)\n\t\t\t} else {\n\t\t\t\treturn errors.Wrapf(err, \"unable to process directory %q\", entry.Name())\n\t\t\t}\n\t\t} else {\n\t\t\tparentDirBuilder.AddEntry(de)\n\t\t}\n\n\t\treturn nil\n\n\tcase fs.Symlink:\n\t\tcompressor := policyTree.Child(entry.Name()).EffectivePolicy().MetadataCompressionPolicy.MetadataCompressor()\n\t\tde, err := u.uploadSymlinkInternal(ctx, entryRelativePath, entry, compressor)\n\n\t\treturn u.processEntryUploadResult(ctx, de, err, entryRelativePath, parentDirBuilder,\n\t\t\tpolicyTree.EffectivePolicy().ErrorHandlingPolicy.IgnoreFileErrors.OrDefault(false),\n\t\t\tu.OverrideEntryLogDetail.OrDefault(policyTree.EffectivePolicy().LoggingPolicy.Entries.Snapshotted.OrDefault(policy.LogDetailNone)),\n\t\t\t\"snapshotted symlink\", t0)\n\n\tcase fs.File:\n\t\tatomic.AddInt32(&u.stats.NonCachedFiles, 1)","sourceCodeStart":880,"sourceCodeEnd":916,"githubUrl":"https://github.com/kopia/kopia/blob/82495e54b584c1ef6073c9e1be048f57f8aef078/snapshot/upload/upload.go#L880-L916","documentation":"When processing a child directory fails with an error that is NOT a dirReadError, processSingle treats it as fatal for the upload and wraps it with 'unable to process directory %q'. dirReadError failures (e.g. permission or IO problems reading a directory) are instead reported per policy and possibly ignored; any other failure type aborts the whole snapshot upload.","triggerScenarios":"processEntryUploadResult or another step for a child directory returns a non-dirReadError error during processDirectoryEntries — e.g. upload/object-write failures, checkpoint errors, or panics converted to errors while processing entry.Name().","commonSituations":"Storage backend failure mid-snapshot causing non-read errors while walking the tree; bug or unexpected state in entry upload results; unusual filesystem entries causing type errors (cascading from 'invalid entry type'); running out of memory during very wide directory scans.","solutions":["Read the %q name and the wrapped cause to locate the failing directory and underlying error type","If the cause is an entry-type problem, fix or exclude that filesystem entry via ignore rules","Verify repository storage health if the cause is an upload/write failure","If it's a policy-action error surfacing as a non-dirReadError, correct the action script"],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"info, err := os.Stat(dirPath)\nif err != nil || !info.IsDir() {\n    return fmt.Errorf(\"%s is not a readable directory: %w\", dirPath, err)\n}","typeGuard":null,"tryCatchPattern":"err := uploadDir(ctx, ...)\nvar dre dirReadError\nif errors.As(err, &dre) {\n    // policy-controlled: report and maybe ignore\n    reportError(dre.error)\n} else if strings.Contains(err.Error(), \"unable to process directory\") {\n    log.Fatalf(\"fatal failure processing %v: %v\", dirPath, err)\n    return err\n}","preventionTips":["Read the %q directory name in the message to isolate the failing subtree","Exclude problematic paths via ignore rules","Validate repository storage health before large tree uploads","Keep kopia up to date; non-dirReadError aborts often indicate bugs or type issues"],"tags":["directory","upload","snapshot"],"backgroundTag":"directory-processing-failed","analyzedSha":"82495e54b584c1ef6073c9e1be048f57f8aef078","analyzedAt":"2026-09-07T20:35:21.689Z","contentChangedAt":"2026-09-07T20:35:21.689Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}