How the WeKnora System-Admin Dashboard Displays Failed Tasks and Enables Manual Retries

The WeKnora system-admin dashboard visualizes failed background jobs through a Vue-based interface that queries the runtime-task inspector backend, allowing privileged operators to retry archived or failed tasks via the run_now action after state validation.

The Tencent/WeKnora repository implements a distributed task queue system that requires administrative oversight when asynchronous jobs fail. The system-admin dashboard provides operators with real-time visibility into task states and secure mechanisms for manual intervention. This architecture coordinates between Go-based backend inspectors, TypeScript API clients, and Vue frontend components to deliver a complete task recovery workflow.

Backend Runtime-Task Inspector Architecture

The foundation of failed task visibility rests on the runtime-task inspector, which exposes job states and permissible operations through carefully defined Go structs and state machines.

Task State Representation

The internal/types/runtime_task.go file defines the public projection of queue entries through the RuntimeTaskInfo struct. This structure includes a State field that tracks the task lifecycle through values such as pending, active, scheduled, retry, archived, and completed. Crucially, the struct also carries an AllowedActions slice that dynamically lists operations the operator may perform, such as cancel, run_now, and delete.

According to the WeKnora source code, the inspector implements cursor-based pagination via ListRuntimeTasks, which returns a RuntimeTaskPage containing task slices and a NextCursor anchor. These cursors remain valid even when tasks are deleted, ensuring stable pagination across volatile datasets.

State-to-Action Mapping Logic

The mapping between task states and available actions occurs in internal/router/task_inspector.go. The runtimeTaskActions function (lines 285-299) implements the authorization logic:

func runtimeTaskActions(info types.RuntimeTaskInfo) []types.RuntimeTaskAction {
    actions := []types.RuntimeTaskAction{}
    switch info.State {
    case types.RuntimeTaskPending, types.RuntimeTaskActive,
         types.RuntimeTaskScheduled, types.RuntimeTaskRetry:
        actions = append(actions, types.RuntimeTaskActionCancel)
    case types.RuntimeTaskScheduled, types.RuntimeTaskRetry:
        actions = append(actions, types.RuntimeTaskActionRunNow)
    case types.RuntimeTaskArchived:
        actions = append(actions, types.RuntimeTaskActionRunNow, types.RuntimeTaskActionDelete)
    }
    return actions
}

When a task reaches the archived state—indicating permanent failure or exhaustion of automatic retries—the system grants the run_now and delete actions. This state machine ensures that operators cannot execute invalid transitions, such as retrying a task that is already active.

REST API Layer for Task Management

The frontend communicates with the inspector through the system API defined in frontend/src/api/system/index.ts. This layer wraps backend endpoints with TypeScript interfaces for type safety.

Fetching Paginated Task Lists

The getRuntimeTasks function retrieves task pages for dashboard display:

export async function getRuntimeTasks(
  queue: string,
  state: RuntimeTaskState,
  cursor: string,
  limit: number,
): Promise<RuntimeTaskPage> {
  return request.get<RuntimeTaskPage>(`/system/runtime-task/${queue}/${state}`, {
    params: { cursor, limit },
  });
}

This endpoint delivers task metadata including state, allowed_actions, and a redacted payload that omits sensitive document content or secret keys. The cursor parameter accepts base-64 encoded anchors limited to 32 entries, maintaining pagination stability across task deletions.

Executing Task Mutations

Manual retries invoke the mutateRuntimeTask function, which sends a POST request to /system/runtime-task/:queue/:taskID/:action. The backend validates the requested action against the task’s AllowedActions list before invoking RunRuntimeTask, CancelRuntimeTask, or DeleteRuntimeTask on the inspector instance.

Vue Dashboard Frontend Implementation

The administrative interface resides in frontend/src/views/system/RuntimeQueues.vue, which renders queue tables and handles operator interactions.

Rendering Failed Task States

The dashboard queries getRuntimeTasks on mount and whenever operators switch between queue tabs. Tasks render with color-coded status indicators where queueState(row).tone applies red styling to failed or archived entries. When a task’s state equals retry or archived, the UI displays a "failed" badge alongside action buttons.

Manual Retry Workflow

The retry interaction follows a strict four-step sequence:

  1. Operator clicks Retry – The button invokes mutateRuntimeTask(queue, task.id, 'run_now').
  2. Backend validates – The inspector checks that run_now exists in the task’s AllowedActions.
  3. State transition – If permitted, the task moves from archived or retry back to pending, resetting its retry counter.
  4. UI refresh – The dashboard re-fetches the task list, displaying the recovered job under the pending column.

The Vue template implements the retry trigger as follows:

<t-button @click="mutateRuntimeTask(queue, task.id, 'run_now')">
  {{ t('system.globalSettings.runtime.actions.retry') }}
</t-button>

After triggering the mutation, the component refreshes the local task state:

const response = await getRuntimeTasks(queue, requestedState, cursor, TASK_PAGE_SIZE);
tasks.value = response.tasks;

Audit Logging Integration

Every manual intervention generates traceable records. The SystemAuditLog.vue component (lines 257-333) captures events such as system.queue_task_retried and system.queue_task_deleted, creating an immutable history of operator actions for compliance and debugging purposes.

Security and Observability Safeguards

The dashboard implements defense-in-depth measures when exposing internal task data. The inspector redacts payloads by whitelisting only metadata fields such as tenant identifiers, knowledge-base references, and task IDs. Sensitive document content and cryptographic keys remain inaccessible to administrative users.

Pagination cursors utilize base-64 encoding with a maximum of 32 anchors, ensuring that cursor references survive task deletions without leaking internal database identifiers. This design prevents enumeration attacks while maintaining usability for large task queues.

Summary

  • State Machine: The runtimeTaskActions function in internal/router/task_inspector.go maps archived and retry states to permissible run_now and delete actions.
  • API Surface: TypeScript wrappers in frontend/src/api/system/index.ts provide type-safe access to cursor-paginated task lists and mutation endpoints.
  • Frontend Interface: RuntimeQueues.vue renders failed tasks with color-coded badges and triggers retries through validated mutateRuntimeTask calls.
  • Audit Trail: SystemAuditLog.vue records all manual retry operations for operational accountability.
  • Security: Payload redaction and stable cursor pagination protect sensitive data while enabling efficient administrative workflows.

Frequently Asked Questions

How does WeKnora determine which actions are available for a failed task?

The system evaluates the task’s current State field against the runtimeTaskActions function in internal/router/task_inspector.go. For tasks in the archived state—representing permanently failed jobs—the function returns run_now and delete as the only valid AllowedActions. The backend enforces these constraints by checking the requested action against this list before executing any mutation.

What is the difference between the 'retry' and 'archived' states in WeKnora?

The retry state indicates a task that has failed temporarily and may undergo automatic reprocessing according to the queue’s backoff policy. The archived state represents final failure after exhausting all retry attempts. While both states display as "failed" in the dashboard, only archived tasks permit permanent deletion, whereas both support the run_now action for manual re-enqueueing.

How does the dashboard ensure security when displaying task details?

The runtime-task inspector implements payload redaction in the API layer, exposing only whitelisted metadata such as tenant IDs and task identifiers while withholding document content and secret keys. Additionally, the system uses base-64 encoded pagination cursors limited to 32 anchors to prevent information leakage through cursor manipulation, as documented in the async-task architecture guides.

What happens to the audit log when a manual retry is triggered?

The SystemAuditLog.vue component captures the system.queue_task_retried event immediately upon successful mutation. This record includes the operator identity, timestamp, queue name, and task ID, creating a permanent trail that satisfies compliance requirements and enables post-incident analysis of manual interventions in the task queue.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →