{"record":{"id":"f7b48a81b76a7b62","repo":"HeyPuter/puter","slug":"shortcut-target-not-found","errorCode":"shortcut_target_not_found","errorMessage":"shortcut op missing `name`","messagePattern":"shortcut op missing `name`","errorType":"http","errorClass":"HttpError","httpStatus":400,"severity":"error","filePath":"src/backend/controllers/fs/LegacyFSController.ts","lineNumber":2238,"sourceCode":"                        path: targetPath,\n                        dedupeName: getBoolean(record, 'dedupe_name') ?? true,\n                        createMissingParents:\n                            getBoolean(\n                                record,\n                                'create_missing_ancestors',\n                                'create_missing_parents',\n                            ) ?? false,\n                    });\n                    await this.#emitGuiEvent('outer.gui.item.added', entry);\n                    shaped = await toLegacyEntry(this.clients.event, entry);\n                } else if (op === 'shortcut') {\n                    const parentPath = getString(record, 'path') ?? '';\n                    const name = getString(record, 'name');\n                    const shortcutToUid =\n                        getString(record, 'shortcut_to_uid') ??\n                        getString(record, 'shortcut_to');\n                    if (!name) {\n                        throw new HttpError(400, 'shortcut op missing `name`', {\n                            legacyCode: 'shortcut_target_not_found',\n                        });\n                    }\n                    if (!shortcutToUid) {\n                        throw new HttpError(\n                            400,\n                            'shortcut op missing `shortcut_to_uid`',\n                            { legacyCode: 'shortcut_target_not_found' },\n                        );\n                    }\n                    const target = await resolveV1Selector(\n                        this.stores.fsEntry,\n                        { uid: shortcutToUid },\n                    );\n                    const expandedParent = this.#expandTilde(\n                        parentPath,\n                        username,\n                    );","sourceCodeStart":2220,"sourceCodeEnd":2256,"githubUrl":"https://github.com/HeyPuter/puter/blob/908ec23eda38526170322c3edf71ba45ecb1ca95/src/backend/controllers/fs/LegacyFSController.ts#L2220-L2256","documentation":"A `shortcut` op in POST /batch requires a `name` for the new shortcut entry. Note the legacyCode here is `shortcut_target_not_found` (historical mismatch), even though the HTTP status is 400 and the real cause is the missing name, not a missing target.","triggerScenarios":"Sending `{op:'shortcut', shortcut_to_uid: targetUid}` without `name`. The name is the shortcut's own filename, not the target's.","commonSituations":"Caller assumes the shortcut inherits the target's name; field naming confusion between `name` (the link) and `shortcut_to_uid` (the target).","solutions":["Set `name` to the desired shortcut filename (e.g. `Link to foo.lnk`).","Remember the legacyCode `shortcut_target_not_found` can fire for a missing name — read the message, not just the code."],"exampleFix":"// before\nops.push({ op: 'shortcut', path: '~/desktop', shortcut_to_uid: targetUid });\n\n// after\nops.push({ op: 'shortcut', path: '~/desktop', name: 'My Shortcut', shortcut_to_uid: targetUid });","handlingStrategy":"validation","validationCode":"for (const op of ops) { if (op.op === 'shortcut' && !op.name) throw new Error('shortcut op needs name'); }","typeGuard":"function isValidShortcutOp(op) { return op.op === 'shortcut' && typeof op.name === 'string' && op.name.length > 0; }","tryCatchPattern":null,"preventionTips":["name is the link's filename, not the target's.","Read the error message — legacyCode shortcut_target_not_found also fires for missing name."],"tags":["batch","shortcut","validation","bad-request"],"backgroundTag":null,"analyzedSha":"908ec23eda38526170322c3edf71ba45ecb1ca95","analyzedAt":"2026-08-12T20:53:15.911Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}