{"record":{"id":"b5aaad27f422efa4","repo":"HeyPuter/puter","slug":"dest-is-not-a-directory-b5aaad","errorCode":"dest_is_not_a_directory","errorMessage":"Target is not a directory","messagePattern":"Target is not a directory","errorType":"http","errorClass":"HttpError","httpStatus":400,"severity":"error","filePath":"src/backend/controllers/fs/LegacyFSController.ts","lineNumber":525,"sourceCode":"                    }),\n                ),\n            );\n            if (paginated) {\n                res.json({\n                    items: shaped,\n                    ...(body.includeTotal === true\n                        ? { total: shaped.length }\n                        : {}),\n                });\n                return;\n            }\n            res.json(shaped);\n            return;\n        }\n\n        const parent = await resolveV1Selector(this.stores.fsEntry, body);\n        if (!parent.isDir) {\n            throw new HttpError(400, 'Target is not a directory', {\n                legacyCode: 'dest_is_not_a_directory',\n            });\n        }\n        await assertAccess(\n            this.services.acl,\n            this.services.fs,\n            actor,\n            parent.path,\n            'list',\n        );\n\n        const sortBy = this.#parseSortBy(body);\n        const sortOrder = this.#parseSortOrder(body);\n        const limit =\n            typeof body.limit === 'number' || typeof body.limit === 'string'\n                ? Number(body.limit)\n                : undefined;\n        const offset =","sourceCodeStart":507,"sourceCodeEnd":543,"githubUrl":"https://github.com/HeyPuter/puter/blob/908ec23eda38526170322c3edf71ba45ecb1ca95/src/backend/controllers/fs/LegacyFSController.ts#L507-L543","documentation":"Thrown by LegacyFSController (readdir/list-type flow) after resolveV1Selector resolves the target entry and parent.isDir is false. The endpoint is meant to list directory contents, so a file target is rejected with legacyCode 'dest_is_not_a_directory'.","triggerScenarios":"Calling readdir with a path or uid that points to a regular file rather than a directory; passing a file uid where a folder uid was expected.","commonSituations":"User selecting a file in a 'browse folder' dialog; a stored uid referencing a file that the UI assumes is a folder; a path computed by joining a filename instead of a folder.","solutions":["Resolve the target client-side (stat) and verify it is a directory before calling readdir.","If listing siblings, derive the parent directory path with posix.dirname before calling.","Confirm the uid/path you pass corresponds to a folder entry."],"exampleFix":"// before\nreaddir({ path: '/docs/readme.md' }); // file, not a dir\n\n// after\nreaddir({ path: '/docs' });","handlingStrategy":"type-guard","validationCode":"const target = await stat(selector);\nif (!target.is_dir) throw new Error('Target is not a directory; use readdir on a folder');","typeGuard":"function isDirectoryEntry(e) { return !!e && !!e.is_dir; }","tryCatchPattern":"null","preventionTips":["Stat the target before calling readdir.","Use dirname to list siblings of a file.","Validate folder selection in the UI."],"tags":["fs","legacy","readdir","validation"],"backgroundTag":null,"analyzedSha":"908ec23eda38526170322c3edf71ba45ecb1ca95","analyzedAt":"2026-08-12T20:53:15.911Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}