vxcontrol/pentagi · error
failed to create tool call log: %w
Error message
failed to create tool call log: %w
What it means
PutLog persists a tool call record via db.CreateToolcall before executing tool logic. This error wraps any PostgreSQL failure during that insert (connection loss, FK violation on flow_id/task_id/subtask_id, context cancellation, constraint violation). It is a wrapper, so the root cause is always in the %w-wrapped error.
Source
Thrown at backend/pkg/controller/tclog.go:68
name string,
args json.RawMessage,
taskID *int64,
subtaskID *int64,
) (int64, error) {
w.mx.Lock()
defer w.mx.Unlock()
tc, err := w.db.CreateToolcall(ctx, database.CreateToolcallParams{
CallID: callID,
Status: database.ToolcallStatusRunning,
Name: name,
Args: args,
FlowID: w.flowID,
TaskID: database.Int64ToNullInt64(taskID),
SubtaskID: database.Int64ToNullInt64(subtaskID),
})
if err != nil {
return 0, fmt.Errorf("failed to create tool call log: %w", err)
}
w.pub.ToolCallLogAdded(ctx, tc)
return tc.ID, nil
}
func (w *flowToolCallLogWorker) UpdateLogSuccess(
ctx context.Context,
id int64,
result string,
durationSeconds float64,
) error {
tc, err := w.db.UpdateToolcallFinishedResult(ctx, database.UpdateToolcallFinishedResultParams{
Result: result,
DurationSeconds: durationSeconds,
ID: id,
})View on GitHub (pinned to ea665308ba)
Solutions
- Inspect the wrapped cause with errors.Unwrap / %v to distinguish FK violation vs connection error
- Verify taskID/subtaskID belong to the same flow and still exist before calling PutLog
- Check PostgreSQL logs for the exact constraint (e.g. toolcalls_subtask_id_fkey)
- Ensure pgvector/Postgres container is healthy (docker compose ps, connection pool limits)
- Retry on transient errors (pq: connection reset, driver.ErrBadConn) only; do not retry FK violations
Example fix
// before
id, err := worker.PutLog(ctx, callID, name, args, &staleTaskID, &staleSubtaskID)
// after
var taskID, subtaskID int64 = staleTaskID, staleSubtaskID
if !taskExists(ctx, db, taskID) || !subtaskInFlow(ctx, db, subtaskID, flowID) {
taskID, subtaskID = 0, 0 // pass nil instead of dangling FKs
}
id, err := worker.PutLog(ctx, callID, name, args, maybePtr(taskID), maybePtr(subtaskID)) Defensive patterns
Strategy: validation
Validate before calling
func canLog(ctx context.Context, q database.Querier, flowID int64, taskID, subtaskID *int64) error {
if ctx.Err() != nil { return ctx.Err() }
if taskID != nil {
if _, err := q.GetFlowTask(ctx, flowID, *taskID); err != nil { return fmt.Errorf("task %d not in flow %d: %w", *taskID, flowID, err) }
}
if subtaskID != nil {
if _, err := q.GetSubtask(ctx, *subtaskID); err != nil { return fmt.Errorf("subtask %d missing: %w", *subtaskID, err) }
}
return nil
} Type guard
func isForeignKeyErr(err error) bool {
var pgErr *pgconn.PgError
return errors.As(err, &pgErr) && pgErr.Code == "23503"
} Try / catch
id, err := worker.PutLog(ctx, callID, name, args, taskID, subtaskID)
if err != nil {
switch {
case isForeignKeyErr(err):
log.Warn().Err(err).Msg("dangling task/subtask reference; logging without FKs")
id, err = worker.PutLog(ctx, callID, name, args, nil, nil)
case errors.Is(err, context.Canceled):
return err
default:
return fmt.Errorf("putlog: %w", err)
}
} Prevention
- Always take taskID/subtaskID from the same agent iteration that owns the flow
- Never reuse IDs from a previous flow run
- Check ctx.Err() before long DB writes
- Alert on Postgres constraint 23503 occurrences to find lifecycle races
- Monitor DB connection health during long agent runs
When it happens
Trigger: Calling PutLog with a subtaskID whose row was already deleted (FK violation), a taskID from another flow, an invalid JSON args blob rejected by a jsonb column, or while the DB connection is down/canceled ctx.
Common situations: Agents racing subtask cleanup so the subtask row disappears mid-run; transient DB restarts during long flows; passing task IDs from a stale/foreign flow after flow recreation.
Related errors
- failed to create termlog: %w
- failed to update tool call log result: %w
- failed to update tool call log failed result: %w
- failed to get containers: %w
- knowledge: list user docs: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/a63825fa4b0c774e.
Report an issue: GitHub.