wtfutil/wtf · error

error fetching task: %s

Error message

error fetching task: %s

What it means

Returned by toggleTaskCompletionById when asana.Task.Fetch fails to retrieve the task before toggling its completed flag. The library must fetch the task first to read its current Completed status; if that read fails (bad task ID, permissions, network), this error is produced. The toggle is not performed.

Source

Thrown at modules/asana/client.go:119

		return nil, fmt.Errorf("error fetching tasks: %s", err)
	}

	processFetchedTasks(client, &fetchedTasks, &taskItems, &uidToName, mode, workspaceId, uid)

	return taskItems, nil

}

func toggleTaskCompletionById(token, taskId string) error {
	client := asana.NewClientWithAccessToken(token)

	t := &asana.Task{
		ID: taskId,
	}

	err := t.Fetch(client)
	if err != nil {
		return fmt.Errorf("error fetching task: %s", err)
	}

	updateReq := &asana.UpdateTaskRequest{}

	if *t.Completed {
		f := false
		updateReq.Completed = &f
	} else {
		t := true
		updateReq.Completed = &t
	}

	err = t.Update(client, updateReq)
	if err != nil {
		return fmt.Errorf("error updating task: %s", err)
	}

	return nil

View on GitHub (pinned to bb838c1ccb)

Solutions

  1. Verify the task GID exists: curl -H 'Authorization: Bearer <token>' https://app.asana.com/api/1.0/tasks/<gid>.
  2. Confirm the token has read access to the workspace/project containing the task.
  3. Refresh any cached task IDs — the task may have been deleted or permanently completed.
  4. Retry if the wrapped error indicates a transient network or 5xx condition.

Example fix

// before
err := t.Fetch(client)
if err != nil {
    return fmt.Errorf("error fetching task: %s", err)
}
// after
err := t.Fetch(client)
if err != nil {
    return fmt.Errorf("error fetching task %s before toggle: %w", taskId, err)
}
Defensive patterns

Strategy: validation

Validate before calling

func taskExists(client *asana.Client, taskId string) error {
    if taskId == "" {
        return fmt.Errorf("empty task id")
    }
    t := &asana.Task{ID: taskId}
    if err := t.Fetch(client); err != nil {
        return fmt.Errorf("task %s not accessible: %w", taskId, err)
    }
    return nil
}

Type guard

func validTaskID(id string) bool {
    if id == "" { return false }
    for _, r := range id {
        if r < '0' || r > '9' { return false }
    }
    return true
}

Try / catch

err := mod.Toggle(taskId)
if err != nil {
    if strings.Contains(err.Error(), "error fetching task") {
        log.Printf("task %s missing or inaccessible, refreshing ID cache", taskId)
        return refreshAndRetry(taskId)
    }
    return err
}

Prevention

When it happens

Trigger: Calling toggleTaskCompletion with a task GID that does not exist or is inaccessible: task deleted or moved to another project the token can't see, typo'd GID, invalid/expired token, or network failure during t.Fetch(client).

Common situations: Stale task ID cached from a previous sync after the task was deleted in Asana; token lost access to the task's workspace; offline/VPN issues; GID copied incorrectly (Asana GIDs are long numeric strings).

Related errors


AI-assisted analysis of wtfutil/wtf@bb838c1ccb (2026-09-03). Data as JSON: /api/errors/2a9e9c2fea371ee0. Report an issue: GitHub.