{"record":{"id":"bbc1e2356a68ab77","repo":"kopia/kopia","slug":"unsupported-entry-type-v","errorCode":null,"errorMessage":"unsupported entry type: %v","messagePattern":"unsupported entry type: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fs/localfs/shallow_fs.go","lineNumber":37,"sourceCode":"// directory trees in a restore image. A placeholder for directory d1 is\n// d1.kopia-entry/.kopia-entry. As a result, d1.kopia-entry will stat as\n// a directory and show up nicely in colorized ls output. A placeholder\n// for a file f1 is f1.kopia-entry.\n\nfunc placeholderPath(path string, et snapshot.EntryType) (string, error) {\n\tswitch et {\n\tcase snapshot.EntryTypeFile:\n\t\treturn path + ShallowEntrySuffix, nil\n\tcase snapshot.EntryTypeDirectory: // Directories and regular files\n\t\tdirpath := path + ShallowEntrySuffix\n\t\tif err := os.MkdirAll(ospath.SafeLongFilename(dirpath), os.FileMode(dirMode)); err != nil {\n\t\t\treturn \"\", errors.Wrap(err, \"placeholderPath dir creation\")\n\t\t}\n\n\t\treturn filepath.Join(dirpath, ShallowEntrySuffix), nil\n\tdefault:\n\t\t// Shouldn't be used on links or other file types.\n\t\treturn \"\", errors.Errorf(\"unsupported entry type: %v\", et)\n\t}\n}\n\n// WriteShallowPlaceholder writes sufficient metadata into the placeholder\n// file associated with path so that it can be roundtripped through\n// snapshot/restore without needing to be realized in the local\n// filesystem.\n// TODO(rjk): Should the placeholder use the complete fs.Entry?\nfunc WriteShallowPlaceholder(path string, de *snapshot.DirEntry) (string, error) {\n\tbuffy := &bytes.Buffer{}\n\tencoder := json.NewEncoder(buffy)\n\n\tif err := encoder.Encode(de); err != nil {\n\t\treturn \"\", errors.Wrapf(err, \"json encoding DirEntry\")\n\t}\n\n\tmp, err := placeholderPath(path, de.Type)\n\tif err != nil {","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/kopia/kopia/blob/82495e54b584c1ef6073c9e1be048f57f8aef078/fs/localfs/shallow_fs.go#L19-L55","documentation":"placeholderPath only supports snapshot.EntryTypeFile and snapshot.EntryTypeDirectory. If WriteShallowPlaceholder is called for a symlink, device, socket, or any other entry type, it returns this errors.Errorf because placeholder files are not defined for those types.","triggerScenarios":"Calling WriteShallowPlaceholder with a *snapshot.DirEntry whose Type is EntryTypeSymlink, EntryTypeDevice, EntryTypeSocket, etc. — e.g. when walking a source tree that contains symlinks or devices and writing placeholders for every entry.","commonSituations":"Copy/restore pipelines that blindly call writeShallowEntry on all DirEntries including symlinks; snapshot entries produced on Unix with device nodes being replayed through the shallow-placeholder API.","solutions":["Filter entries: only call WriteShallowPlaceholder for files and directories; handle symlinks/other types separately (e.g. recreate the symlink directly)","Check de.Type before invoking the placeholder writer and skip unsupported types","If symlinks should be supported, update the calling code path rather than this library function"],"exampleFix":"// before\nfor _, de := range dirEntries {\n\tlocalfs.WriteShallowPlaceholder(dest, de) // panics on symlinks\n}\n// after\nfor _, de := range dirEntries {\n\tswitch de.Type {\n\tcase snapshot.EntryTypeFile, snapshot.EntryTypeDirectory:\n\t\tlocalfs.WriteShallowPlaceholder(dest, de)\n\tdefault:\n\t\t// recreate symlinks/other types directly\n\t\tcopyNonPlaceholderEntry(dest, de)\n\t}\n}","handlingStrategy":"type-guard","validationCode":"switch de.Type {\ncase snapshot.EntryTypeFile, snapshot.EntryTypeDirectory:\n\t// OK to write placeholder\ndefault:\n\treturn fmt.Errorf(\"no placeholder support for type %v\", de.Type)\n}","typeGuard":"func placeholderSupported(t snapshot.EntryType) bool {\n\treturn t == snapshot.EntryTypeFile || t == snapshot.EntryTypeDirectory\n}","tryCatchPattern":"if !placeholderSupported(de.Type) {\n\treturn handleNonPlaceholder(de) // recreate symlink/device directly\n}\nif _, err := localfs.WriteShallowPlaceholder(path, de); err != nil {\n\treturn fmt.Errorf(\"placeholder %q: %w\", path, err)\n}","preventionTips":["Check de.Type before writing placeholders","Handle symlinks by recreating them rather than placeholdering","Keep placeholder writing restricted to file/dir entries in your pipeline","Document that shallow placeholders apply only to files and directories"],"tags":["filesystem","localfs","shallow-placeholder","unsupported-type"],"backgroundTag":"unsupported-operation","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"}