HeyPuter/puter · error · HttpError

shortcut_target_not_found

shortcut_target_not_found

Error message

shortcut op missing `name`

What it means

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.

Source

Thrown at src/backend/controllers/fs/LegacyFSController.ts:2238

                        path: targetPath,
                        dedupeName: getBoolean(record, 'dedupe_name') ?? true,
                        createMissingParents:
                            getBoolean(
                                record,
                                'create_missing_ancestors',
                                'create_missing_parents',
                            ) ?? false,
                    });
                    await this.#emitGuiEvent('outer.gui.item.added', entry);
                    shaped = await toLegacyEntry(this.clients.event, entry);
                } else if (op === 'shortcut') {
                    const parentPath = getString(record, 'path') ?? '';
                    const name = getString(record, 'name');
                    const shortcutToUid =
                        getString(record, 'shortcut_to_uid') ??
                        getString(record, 'shortcut_to');
                    if (!name) {
                        throw new HttpError(400, 'shortcut op missing `name`', {
                            legacyCode: 'shortcut_target_not_found',
                        });
                    }
                    if (!shortcutToUid) {
                        throw new HttpError(
                            400,
                            'shortcut op missing `shortcut_to_uid`',
                            { legacyCode: 'shortcut_target_not_found' },
                        );
                    }
                    const target = await resolveV1Selector(
                        this.stores.fsEntry,
                        { uid: shortcutToUid },
                    );
                    const expandedParent = this.#expandTilde(
                        parentPath,
                        username,
                    );

View on GitHub (pinned to 908ec23eda)

Solutions

  1. Set `name` to the desired shortcut filename (e.g. `Link to foo.lnk`).
  2. Remember the legacyCode `shortcut_target_not_found` can fire for a missing name — read the message, not just the code.

Example fix

// before
ops.push({ op: 'shortcut', path: '~/desktop', shortcut_to_uid: targetUid });

// after
ops.push({ op: 'shortcut', path: '~/desktop', name: 'My Shortcut', shortcut_to_uid: targetUid });
Defensive patterns

Strategy: validation

Validate before calling

for (const op of ops) { if (op.op === 'shortcut' && !op.name) throw new Error('shortcut op needs name'); }

Type guard

function isValidShortcutOp(op) { return op.op === 'shortcut' && typeof op.name === 'string' && op.name.length > 0; }

Prevention

When it happens

Trigger: Sending `{op:'shortcut', shortcut_to_uid: targetUid}` without `name`. The name is the shortcut's own filename, not the target's.

Common situations: Caller assumes the shortcut inherits the target's name; field naming confusion between `name` (the link) and `shortcut_to_uid` (the target).

Related errors


AI-assisted analysis of HeyPuter/puter@908ec23eda (2026-08-12). Data as JSON: /api/errors/f7b48a81b76a7b62. Report an issue: GitHub.