🐛 Bug: Copied editor images can never be restored (legacy restore endpoint always 404)
Los mantenedores suelen responder en 1 día
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 35/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Estancado
- Stack tecnológico
- typescript
- Área
- backend-api-design, frontend
Línea de trabajo
Read the restore handlers in apps/web/hooks/editor/use-editor-config.ts and apps/space/helpers/editor.helper.ts, then trace the legacy and v2 restore calls described in the issue. Confirm how each handler chooses an endpoint for an absolute v2 asset URL. Done means restoring that image uses the working v2 endpoint; issue #9994 already has an open linked pull request.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Is there an existing issue for this?
- I have searched the existing issues
Current behavior
Images whose node src is an absolute v2 asset URL can never be restored once their asset gets soft-deleted, so they stay broken ("Error loading image") forever.
Such nodes are common: copying an image from a rendered editor and pasting it produces
<img data-id="…" src="https://plane.example.com/api/assets/v2/workspaces/<slug>/projects/<project_id>/<asset_id>/" …>
i.e. the resolved URL instead of the asset id.
The editor file handler decides the restore endpoint only by src.startsWith("http")
(apps/web/hooks/editor/use-editor-config.ts, same in apps/space/helpers/editor.helper.ts):
restore: async (src: string) => {
if (src?.startsWith("http")) {
await fileService.restoreOldEditorAsset(workspaceId, src); // POST /api/workspaces/file-assets/<workspace_id>/<last path segment>/restore/
} else {
await fileService.restoreNewAsset(workspaceSlug, src); // POST /api/assets/v2/workspaces/<slug>/restore/<asset_id>/
}
},
For an absolute v2 URL the last path segment is the asset id, but the legacy endpoint (FileAssetViewSet.restore) looks the asset up by its storage key (FileAsset.objects.get(asset="<workspace_id>/<asset_id>")), which never matches. The request always fails with 404 (FileAsset matching query does not exist) and the asset stays is_deleted=True / deleted_at set, so GET /api/assets/v2/.../<asset_id>/ keeps returning 404.
On our self-hosted instance every call to the legacy restore endpoint over ~2.5 months failed (51/51 → 404), while the v2 restore endpoint succeeded (62/62 → 204). The soft delete itself is triggered by the editor while the image is still in the document (e.g. cut/paste or undo while composing a work item), so users end up with broken images right after creating the work item.
Steps to reproduce
- Open a work item and add an image to the description.
- Copy that image in the editor and paste it (the pasted node now has the absolute
/api/assets/v2/...URL assrc). - Make the asset soft-deleted (e.g. delete the original image node; the editor sends
DELETE /api/assets/v2/.../<asset_id>/). - Reload the work item: the remaining image fails to load, the editor calls
POST /api/workspaces/file-assets/<workspace_id>/<asset_id>/restore/→ 404, and the image shows "Error loading image" permanently.
Expected: the restore goes to POST /api/assets/v2/workspaces/<slug>/restore/<asset_id>/ (which works) and the image is shown again.
Environment
Production
Browser
Google Chrome
Variant
Self-hosted (Community)
Version
v1.4.2 (logic unchanged on preview as of bab49bb)
- Lenguaje dominante
- TypeScript
- Estrellas
- 61.5k
- Forks
- 6.2k
- Merge medio
- 1 d 20 h
- PR fusionados (30 d)
- 75
Preparar el entorno
- Incluye un Dockerfile o un archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de makeplane/plane
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día
-
Missing optional chaining on actor_details and reaction_items in apps/space reactions and votesPosiblemente ocupada @ghazy2001 la tomó hace 2 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
makeplane/plane#10111 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
makeplane/plane#10082 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
[bug]: Email notifications show a broken avatar for users without a profile photoPosiblemente ocupada @gurnoorpannu la tomó hace 17 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
makeplane/plane#10009 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
🐛 Bug: Calendar work items cannot be opened on mobilePosiblemente ocupada @pennnnnnnnnn la tomó hace 19 días. Abierto
Dificultad 1/5 Menos de una hora Aptitud para principiantes 75/100
Los mantenedores suelen responder en 1 día
Todos los issues de makeplane/plane
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
Slaymish/HealthAgent#7 ·
-
area: engine topic: math type: bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 80/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
Get-Concord-AI/concord-mcp#310 ·
Los mantenedores suelen responder en 1 día
-
Correct install_claude: 'marketplace add' over a different source is refused, not replaced in placeAbiertotype:bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 80/100
nightgauge/nightgauge#2804 ·
Los mantenedores suelen responder en 1 día