Skip to content

bug: Inconsistent task ID quoting in tasks.json between 'set task' and 'update task' commands #1583

@SiriusA7

Description

@SiriusA7

Summary

When using the set task command, each task number in tasks.json is saved as a string with quotes (e.g., "id": "3"). However, after running the update task command, the task number is saved as a number without quotes (e. g., "id": 3). This creates an inconsistent representation of task IDs in tasks.json.

Steps to Reproduce

  1. Use set task to add a task. Check tasks.json — task IDs are strings.
  2. Use update task on a task. Check tasks.json — the task ID becomes a number.

Expected Behavior

Task IDs should always be consistently typed in tasks.json, as numbers (without quotes).

Actual Behavior

The type of id flips between string and number depending on which command last updated it.

Technical Details

  • Core logic in packages/tm-core/src/modules/storage/adapters/file-storage/file-storage.ts currently stringifies task IDs before saving.
  • CLI script layer (scripts/modules/utils.js and related helpers) sometimes parses IDs as numbers before saving, especially when updating tasks. The function normalizeTaskIds converts IDs to numbers before passing upstream.
  • This inconsistency also exists in supporting tests, which sometimes expect numeric IDs, further propagating the problem.
  • Merged or mutated objects with number-type IDs are occasionally written through to disk, bypassing the string normalization.

Suggested Fix

  • Normalize task IDs as numbers everywhere: CLI, helpers, and tests should treat task IDs as numbers only.
  • Remove string conversion in the normalizeTaskIds function in scripts/modules/utils.js and enforce numeric type throughout.
  • Audit CLI scripts and helpers to ensure that all written IDs are serialized as numbers in storage.
  • Make all relevant unit/integration tests expect numeric IDs.
  • Add regression tests to enforce this contract.

References (Relevant Code Snippets Included)

  1. normalizeTaskIds (Example: scripts/modules/utils.js)
function normalizeTaskIds(tasks) {
    if (!Array.isArray(tasks)) return;
    tasks. forEach((task) => {
        if (task.id !== undefined) {
            // Should always coerce to number, NOT string
            task.id = parseInt(task.id, 10);
        }
        // ...subtasks handling... 
    });
}
  1. File storage adapter (Example: packages/tm-core/src/modules/storage/adapters/file-storage/file-storage.ts)
private normalizeTaskIds(tasks: Task[]): Task[] {
    return tasks.map((task) => ({
        ...task,
        id: String(task. id), // <--- This should be changed to a number, not string
        // (rest of the object)
    }));
}
  1. Test expectation (should expect numbers)
expect(objectContaining({ id: 2, status: 'done' }))

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:cliCLI functionalityarea:task-managementCore task management featuresbugSomething isn't workingmedium-priorityImportant but not urgent

    Projects

    Status

    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions