vxcontrol/pentagi · error
assistant %d not found
Error message
assistant %d not found
What it means
flowWorker.GetAssistant looks up a registered AssistantWorker by ID under the aws mutex; if the map has no entry it returns 'assistant %d not found'. The registry holds only assistants spawned and still alive on this flow worker — deleted or never-started assistants are absent.
Source
Thrown at backend/pkg/controller/flow.go:598
if err := taw.Finish(ctx); err != nil {
return fmt.Errorf("failed to finish assistant %d: %w", aw.GetAssistantID(), err)
}
}
fw.aws[aw.GetAssistantID()] = aw
return nil
}
func (fw *flowWorker) GetAssistant(ctx context.Context, assistantID int64) (AssistantWorker, error) {
fw.awsMX.Lock()
defer fw.awsMX.Unlock()
if aw, ok := fw.aws[assistantID]; ok {
return aw, nil
}
return nil, fmt.Errorf("assistant %d not found", assistantID)
}
func (fw *flowWorker) DeleteAssistant(ctx context.Context, assistantID int64) error {
fw.awsMX.Lock()
defer fw.awsMX.Unlock()
aw, ok := fw.aws[assistantID]
if ok {
if err := aw.Finish(ctx); err != nil {
return fmt.Errorf("failed to finish assistant %d: %w", assistantID, err)
}
delete(fw.aws, assistantID)
}
if assistant, err := fw.flowCtx.DB.DeleteAssistant(ctx, assistantID); err != nil {
return fmt.Errorf("failed to delete assistant %d: %w", assistantID, err)
} else {View on GitHub (pinned to ea665308ba)
Solutions
- Call ListAssistants first and match the ID against live workers before fetching.
- Re-create/register the assistant via AddAssistant if it should exist but was dropped (e.g. after reload).
- Confirm the assistant belongs to the same flow — IDs are only valid within one flowWorker.
- Treat as not-found (404) in API layers and refresh the client's assistant list.
- Serialize create-then-get sequences to avoid the registration race.
Example fix
// before
aw, err := fw.GetAssistant(ctx, assistantID) // fails after reload: worker not in map
// after
for _, live := range fw.ListAssistants(ctx) {
if live.GetAssistantID() == assistantID {
return use(live)
}
}
return fmt.Errorf("assistant %d is not active on this flow", assistantID) Defensive patterns
Strategy: validation
Validate before calling
live := fw.ListAssistants(ctx)
found := false
for _, a := range live {
if a.GetAssistantID() == assistantID { found = true; break }
}
if !found { return ErrAssistantNotActive } Type guard
func assistantActive(fw FlowWorker, ctx context.Context, id int64) bool {
for _, a := range fw.ListAssistants(ctx) {
if a.GetAssistantID() == id { return true }
}
return false
} Try / catch
aw, err := fw.GetAssistant(ctx, assistantID)
if err != nil {
if strings.Contains(err.Error(), "not found") { return http.StatusNotFound }
return http.StatusInternalServerError
} Prevention
- Refresh assistant IDs after server restarts — in-memory workers don't survive reloads
- Never reuse assistant IDs across flows
- Complete AddAssistant before querying GetAssistant (avoid the registration race)
- Drop cached assistant references after DeleteAssistant succeeds
When it happens
Trigger: Calling GetAssistant with an ID for an assistant that was never added on this flow, was removed via DeleteAssistant, was registered on a different flow's worker, or with a stale ID after flow reload (in-memory map repopulated only for active assistants).
Common situations: Client sends an assistant ID from a previous session after server restart; cross-flow ID reuse; DeleteAssistant already removed the worker but the caller caches the ID; race where the caller queries before AddAssistant completes.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- assistant not found
- flow not found
- failed to get screenshot: %w
- flow not found
- failed to get vector store log: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/964571bd41dd42fe.
Report an issue: GitHub.