vxcontrol/pentagi · error

failed to put terminal log (stdin): %w

Error message

failed to put terminal log (stdin): %w

What it means

Before executing, ExecCommand logs the styled command line to the terminal log store via tlp.PutMsg with TermlogTypeStdin. If that persistence write fails, the command is not run and "failed to put terminal log (stdin): %w" wraps the storage error — logging is treated as mandatory so the audit trail is never lost.

Source

Thrown at backend/pkg/tools/terminal.go:220

	}

	isRunning, err := t.dockerClient.IsContainerRunning(ctx, t.containerLID)
	if err != nil {
		return "", fmt.Errorf("runtime verification failed: %w", err)
	}
	if !isRunning {
		return "", fmt.Errorf("container runtime is not operational")
	}

	if cwd == "" {
		cwd = docker.WorkFolderPathInContainer
	}

	// Format command with working directory and ANSI styling
	styledCommand := fmt.Sprintf("%s $ %s%s%s%s", cwd, ansiColorInputCmd, command, ansiColorReset, ansiLineTerminator)
	_, err = t.tlp.PutMsg(ctx, database.TermlogTypeStdin, styledCommand, t.containerID, t.taskID, t.subtaskID)
	if err != nil {
		return "", fmt.Errorf("failed to put terminal log (stdin): %w", err)
	}

	timeout = t.normalizeExecTimeout(timeout)

	createResp, err := t.dockerClient.ContainerExecCreate(ctx, containerName, client.ExecCreateOptions{
		Cmd:          cmd,
		AttachStdout: true,
		AttachStderr: true,
		WorkingDir:   cwd,
		TTY:          true,
	})
	if err != nil {
		return "", fmt.Errorf("failed to create exec process: %w", err)
	}

	if detach {
		resultChan := make(chan execResult, 1)
		detachedCtx := context.WithoutCancel(ctx)

View on GitHub (pinned to ea665308ba)

Solutions

  1. Inspect the wrapped cause for the underlying DB error
  2. Verify PostgreSQL is up and reachable and migrations have run (goose)
  3. Check DB connection-pool limits vs. concurrent flow count
  4. Retry the command once the DB is healthy

Example fix

// before
out, err := term.ExecCommand(ctx, cwd, cmd, false, timeout) // failed to put terminal log (stdin): dial tcp ... refused
// after
if err := db.Ping(ctx); err != nil {
    return fmt.Errorf("termlog store unavailable: %w", err) // fix DB before executing
}
out, err := term.ExecCommand(ctx, cwd, cmd, false, timeout)
Defensive patterns

Strategy: try-catch

Validate before calling

if err := db.SqlDB().PingContext(ctx); err != nil {
    return fmt.Errorf("termlog store unreachable: %w", err)
}

Try / catch

out, err := term.ExecCommand(ctx, cwd, cmd, false, timeout)
var wrapped interface{ Unwrap() error }
if errors.As(err, &wrapped) && strings.Contains(err.Error(), "failed to put terminal log (stdin)") {
    logger.WithError(errors.Unwrap(err)).Error("termlog write failed; fix DB before retrying commands")
    return err // do not execute unlogged commands
}

Prevention

When it happens

Trigger: PutMsg failing due to PostgreSQL being down/unreachable, the termlog table missing or migrated incorrectly, context cancellation while writing, or connection-pool exhaustion under load.

Common situations: Database container stopped or migrating; connection pool saturated by concurrent flows; pgvector/Postgres version mismatch after upgrade; network blip between backend and DB.

Related errors


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