fix: render single-resource responses without misclassifying labels as a collection - #54
Open
nico-fioretti wants to merge 1 commit into
Conversation
…s a collection formatSuccessMessage classifies response data by probing data.tasks || data.projects || data.labels || data.users || data.items for a collection. When data is a single Task object (the case for vikunja_tasks get and create, which pass the resource directly), the task's own .labels array trips that check. The formatter then renders only the labels as 'Results: N item(s)' and silently drops description, project_id, priority, due_date, done, bucket_id, percent_done, etc. Same effect on create: the freshly-assigned labels become the visible payload while the rest of the new resource disappears. Fix: gate the collection extraction with a 'looks like a single resource' check (has id, has title or name, not an array). When that matches, the existing formatDataItems path handles rendering, which already uses the rich Task formatter for Task-shaped objects (showing title, status, priority, due date, project, labels, assignees and description) and falls back to a compact id/title line for everything else. When it doesn't match, behaviour is unchanged. Tests cover the regression (single Task preserves description and metadata, empty .labels doesn't trigger the false collection match, single Project with .name is recognised) plus a defensive case confirming that a wrapper carrying both id and a tasks array still renders the collection.
This was referenced Jul 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
vikunja_tasks getandvikunja_tasks createreturn responses that drop description, project_id, priority, due_date, done, bucket_id, percent_done and every other field. Only the title and labels survive.Reproducer (against any task with a description and a label):
The task object the wrapper fetched from Vikunja contains description, project_id, priority, due_date, etc. None of them reach the user.
Root cause
formatSuccessMessage(src/utils/simple-response.ts) classifies response data by probing five collection keys:When
datais a single Task object (the case forgetTask/createTask, which pass the resource directly viacreateTaskResponse), the task's ownlabels: Label[]array matches that probe. The formatter then renders only the labels as**Results:** N item(s)and silently drops the rest of the resource.The same bug fires on
create— the freshly-assigned labels become the visible payload while the rest of the new resource disappears.Fix
Gate the collection extraction with a
looksLikeSingleResourcecheck (hasid, hastitleorname, not an array). When that matches, the existingformatDataItemspath handles rendering — it already uses the richformatTaskItemrenderer for Task-shaped objects (title, status, priority, due date, project, labels, assignees, description) and falls back to a compactid/titleline for everything else. When the check doesn't match, behaviour is unchanged.Tests
Four new cases in
tests/utils/simple-response.test.ts:Results: 2 item(s).labels: []doesn't get misclassified as a 0-item collection either.name(Project) rather thantitleis recognised.idand atasksarray still renders the collection (the gate requirestitle|name, not justid).All 20 tests in
tests/utils/simple-response.test.tspass;npm run lintandnpm run typecheckare clean.Pre-existing test failures
npm testreports 24 failing suites (227 tests). All of them fail onupstream/mainbefore this change — none touchsimple-response.ts. Verified locally.Context
Found while running tasks through the wrapper: a
getcame back without the description, the user (me) missed a step in the task body, and only noticed because the same task fetched viaupdatestill returnedpreviousStatewith the full object. The Marea fork (0.2.2-marea.11) ships this same upstreamsimple-response.js, so it's the same bug there.