# Inaccurate celery task status

Getting the [status of a celery task](https://docs.celeryq.dev/en/latest/userguide/tasks.html#states)

> `task_result = AsyncResult(task_id, app=celery_app)`

works correctly if you have a result backend configured and tasks are defined with `@app.task(bind=True)`. The result would be `STARTED`; `SUCCESS`; `FAILURE`; `RETRY`; `REVOKED`.

[![celery state transition](https://cdn.hashnode.com/res/hashnode/image/upload/v1767926044912/69f559e4-3c70-4786-88c4-26fd7f5ebab5.png align="center")](https://kroki.io/mermaid/svg/eNqVVE2P0zAQvfMr5sYuoovEsQekVZtF5WNB_ViEEAfXmaSmrl3s8ab990wcp0n2A4oPOThv3jy_N7YnQThVonRiN7p_-wJ4_Xj1E0ajd_A1u53Obt-PYSn8FnxY7xQR5k9jVmZrbGUiNiLiJ_2O0MXyer7MpmP4Zt0WHeyV3HoIe6C2pI-eZx-ySYTH7g5_oeTmcOFYMGjFWl4Dkrx8onI5_z6GOZI7AjlVlui4cI2FdQiehKNOYBLVCFxNJtlikTpKu9trJPRgrNsJrY-PCm6uZ59W86yVKJRnNB4k7klZ8wiehPXBLor8W8ndl489E-7tlo9SbZRGcMEYZcruLJF_mEpjgpcbzINO0XWwk_7P4hClqKQf84RtBDW-xBLOPe6l0sFeG9mDzXiCwV78GMs5cjobAlu0iuOfes2MIiV0HRfDqg2abkzqpTz8DhjqXAPVXE2wSTaaPPI_1y1ZfGKL7jLlGtlQdgBlaKnqtT6CgCpO7Vn00eEheaW0ZvrkckctCuKrIG0wlPP1eYMkzjtBk8mwSTuyHb0PUqL3RWjH91-8KdchbyF43nIQXFtZ85I6Y04HAhHI7gQpKc5tlSbjgU_CgxRGota9Y-CBXTL_wdwM4pD69IQ0L0GPvI6bbx9c4FV5Bd0Dczno9gd9FnWs)

When staring tasks, I’d always get a `PENDING` status regardless of the queried `task_id`. The `PENDING` state is celery's default state for any task whose status is unknown or has no history.

The workaround: write the `task_id` to Redis (Celery's result backend) on task start, then only report status for `task_id`'s that exist there. Also enable `track_started=True` by default, long-running tasks in chains show as `PENDING` until completion, which is pointless for monitoring.

```python
def trigger_chain(task_chain):
    future = task_chain.apply_async()
    celery_app.backend.client.set(f"{future.id}", "started", ex=86400)

def get_task_result(task_id: str):
    try:
        task_result = AsyncResult(task_id, app=celery_app)
        if task_result.status == "PENDING":
            # Access the backend to check if the task key exists
            backend = celery_app.backend
            task_key, backend_client = (
                backend.get_key_for_task(task_id), gettattr(backend, "client", None
            )

            # Check if the key exists in Redis
            if backend_client and 
                if not ( backend_client.exists(key) or backend_client.exists(task_id)):
                    # Task doesn't exist in the result backend
                    return jsonify(
                        {
                            "error": "Task not found",
                            "task_id": task_id,
                            "message": "No task with this ID exists in the result backend",
                        }
                    ), 404
        # Valid task
        response = {
            "task_id": task_id,
            "status": task_result.status,
        }
```

Happy hackin’

### References:

* [Celery: Task States](https://docs.celeryq.dev/en/latest/userguide/tasks.html#states)
    
* [Task State Transitions](https://kroki.io/mermaid/svg/eNqVVE2P0zAQvfMr5sYuoovEsQekVZtF5WNB_ViEEAfXmaSmrl3s8ab990wcp0n2A4oPOThv3jy_N7YnQThVonRiN7p_-wJ4_Xj1E0ajd_A1u53Obt-PYSn8FnxY7xQR5k9jVmZrbGUiNiLiJ_2O0MXyer7MpmP4Zt0WHeyV3HoIe6C2pI-eZx-ySYTH7g5_oeTmcOFYMGjFWl4Dkrx8onI5_z6GOZI7AjlVlui4cI2FdQiehKNOYBLVCFxNJtlikTpKu9trJPRgrNsJrY-PCm6uZ59W86yVKJRnNB4k7klZ8wiehPXBLor8W8ndl489E-7tlo9SbZRGcMEYZcruLJF_mEpjgpcbzINO0XWwk_7P4hClqKQf84RtBDW-xBLOPe6l0sFeG9mDzXiCwV78GMs5cjobAlu0iuOfes2MIiV0HRfDqg2abkzqpTz8DhjqXAPVXE2wSTaaPPI_1y1ZfGKL7jLlGtlQdgBlaKnqtT6CgCpO7Vn00eEheaW0ZvrkckctCuKrIG0wlPP1eYMkzjtBk8mwSTuyHb0PUqL3RWjH91-8KdchbyF43nIQXFtZ85I6Y04HAhHI7gQpKc5tlSbjgU_CgxRGota9Y-CBXTL_wdwM4pD69IQ0L0GPvI6bbx9c4FV5Bd0Dczno9gd9FnWs)
    
* [Celery: track\_task\_started](https://docs.celeryq.dev/en/latest/userguide/configuration.html#task-track-started)
