{"record":{"id":"c8fcf37e2d7a00a1","repo":"linshenkx/prompt-optimizer","slug":"cannot-delete-the-last-prompt-asset-version","errorCode":null,"errorMessage":"Cannot delete the last prompt asset version","messagePattern":"Cannot delete the last prompt asset version","errorType":"validation","errorClass":"FavoriteValidationError","httpStatus":null,"severity":"error","filePath":"packages/core/src/services/favorite/manager.ts","lineNumber":546,"sourceCode":"\n    try {\n      await this.storageProvider.updateData(this.STORAGE_KEYS.FAVORITES, (favorites: FavoritePrompt[] | null) => {\n        const favoritesList = favorites || [];\n        const index = favoritesList.findIndex(f => f.id === id);\n        if (index === -1) {\n          throw new FavoriteNotFoundError(id);\n        }\n\n        const currentFavorite = favoritesList[index];\n        const metadata = currentFavorite.metadata && typeof currentFavorite.metadata === 'object'\n          ? { ...currentFavorite.metadata }\n          : {};\n        const promptAsset = isPromptAsset(metadata.promptAsset) ? metadata.promptAsset : null;\n        if (!promptAsset) {\n          throw new FavoriteValidationError('Prompt asset is not available for this favorite');\n        }\n        if (promptAsset.versions.length <= 1) {\n          throw new FavoriteValidationError('Cannot delete the last prompt asset version');\n        }\n        if (promptAsset.currentVersionId === versionId) {\n          throw new FavoriteValidationError('Cannot delete the current prompt asset version');\n        }\n\n        const now = Date.now();\n        const nextPromptAsset = deletePromptAssetVersion(promptAsset, versionId, now);\n        if (!nextPromptAsset) {\n          throw new FavoriteValidationError(`Prompt asset version not found: ${versionId}`);\n        }\n\n        const nextFavorite: FavoritePrompt = {\n          ...currentFavorite,\n          updatedAt: now,\n          metadata: {\n            ...metadata,\n            promptAsset: nextPromptAsset,\n          },","sourceCodeStart":528,"sourceCodeEnd":564,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/favorite/manager.ts#L528-L564","documentation":"Thrown by FavoriteManager.deleteFavoritePromptAssetVersion when the prompt asset attached to a favorite has only one version left. The library forbids removing the final version because a prompt asset must always contain at least one usable version; deleting it would leave the favorite with an empty, unusable asset.","triggerScenarios":"Calling deleteFavoritePromptAssetVersion(favoriteId, versionId) on a favorite whose metadata.promptAsset.versions array has length <= 1 — i.e. the asset was created with a single version and no additional versions were ever saved via updateFavoritePromptAsset or similar.","commonSituations":"UI showing a delete button on the only remaining version of a saved prompt; importing favorites from an older export where assets only ever had one version; test fixtures that create a one-version asset and then attempt deletion.","solutions":["Check promptAsset.versions.length > 1 before exposing the delete action (disable/hide the button in the UI)","If you truly want to remove the asset, delete the whole favorite or replace the asset instead of deleting its last version","Add another version first (update the prompt), then delete the old one","Handle FavoriteValidationError and surface a user-friendly message"],"exampleFix":"// before\nawait manager.deleteFavoritePromptAssetVersion(favId, versionId); // throws if last version\n\n// after\nconst fav = await manager.getFavorite(favId);\nconst asset = fav.metadata.promptAsset;\nif (asset && asset.versions.length > 1 && asset.currentVersionId !== versionId) {\n  await manager.deleteFavoritePromptAssetVersion(favId, versionId);\n} else {\n  // hide/disable delete in UI instead\n}","handlingStrategy":"validation","validationCode":"const fav = await manager.getFavorite(favId);\nconst asset = fav.metadata.promptAsset;\nconst canDelete = !!asset && asset.versions.length > 1 && asset.currentVersionId !== versionId;","typeGuard":"const hasMultipleVersions = (a: unknown): a is { versions: unknown[] } =>\n  typeof a === 'object' && a !== null && Array.isArray((a as any).versions) && (a as any).versions.length > 1;","tryCatchPattern":"try { await manager.deleteFavoritePromptAssetVersion(id, vId); } catch (e) { if (e instanceof FavoriteValidationError) { /* show 'cannot delete last version' */ } else throw e; }","preventionTips":["Hide/disable the delete control when versions.length <= 1","Refresh the favorite before showing version actions"],"tags":["favorites","prompt-asset","versioning","validation"],"backgroundTag":"delete-last-resource-version","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}