vxcontrol/pentagi · error

failed to get tool call log: %w

Error message

failed to get tool call log: %w

What it means

GetLog fetches one toolcall row scoped by both id and flowID via db.GetFlowToolcall. Because the query filters on the worker's flowID, requesting an ID that exists but belongs to another flow returns sql.ErrNoRows, wrapped here. Any other DB failure (connection, canceled ctx) is wrapped identically.

Source

Thrown at backend/pkg/controller/tclog.go:122

		DurationSeconds: durationSeconds,
		ID:              id,
	})
	if err != nil {
		return fmt.Errorf("failed to update tool call log failed result: %w", err)
	}

	w.pub.ToolCallLogUpdated(ctx, tc)

	return nil
}

func (w *flowToolCallLogWorker) GetLog(ctx context.Context, id int64) (database.Toolcall, error) {
	tc, err := w.db.GetFlowToolcall(ctx, database.GetFlowToolcallParams{
		ID:     id,
		FlowID: w.flowID,
	})
	if err != nil {
		return database.Toolcall{}, fmt.Errorf("failed to get tool call log: %w", err)
	}

	return tc, nil
}

View on GitHub (pinned to ea665308ba)

Solutions

  1. Check errors.Is(err, sql.ErrNoRows) and surface 404 (not 500) to the caller
  2. Ensure you use the FlowToolCallLogWorker obtained via GetFlowToolCallLog for that specific flow
  3. Validate id > 0 before calling
  4. If the caller has only a toolcall ID, look up its flow first, then fetch the matching worker
  5. Retry transient DB errors with backoff

Example fix

// before
tc, err := wrongFlowWorker.GetLog(ctx, toolcallID) // scope mismatch
// after
worker, err := ctl.GetFlowToolCallLog(ctx, flowID)
if err != nil { return nil, err }
tc, err := worker.GetLog(ctx, toolcallID)
if errors.Is(err, sql.ErrNoRows) { return nil, ErrNotFound }
Defensive patterns

Strategy: type-guard

Validate before calling

func validToolcallID(id int64) bool { return id > 0 }

Type guard

func toolcallNotFound(err error) bool { return errors.Is(err, sql.ErrNoRows) }

Try / catch

tc, err := worker.GetLog(ctx, id)
if toolcallNotFound(err) {
    return nil, newNotFound("tool call", id) // 404, not 500
}
if err != nil {
    return nil, fmt.Errorf("get toolcall: %w", err)
}

Prevention

When it happens

Trigger: Requesting a toolcall ID from a different flow's worker; querying an ID after the flow/rows were deleted; passing an unparsed/zero id; DB unavailable.

Common situations: GraphQL/REST resolvers forwarding client-supplied IDs without scoping; frontend caches holding IDs from a re-created flow; cross-worker lookups in tool implementations.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/85110489a175feea. Report an issue: GitHub.