vxcontrol/pentagi · error
failed to put terminal log (stdout): %w
Error message
failed to put terminal log (stdout): %w
What it means
After a successful exec, getExecResult logs the styled output to the terminal log store via t.tlp.PutMsg with TermlogTypeStdout. This error wraps a failure of that persistence call, meaning the command ran fine but its transcript could not be recorded, so the function aborts to keep the terminal log consistent.
Source
Thrown at backend/pkg/tools/terminal.go:319
"For long batch commands, wrap with shell timeout utility: 'timeout %d <command>' to ensure clean completion",
ctx.Err(),
truncateString(dst.String(), 500),
suggestedTimeout,
)
}
// wait for the exec process to finish
_, err = t.dockerClient.ContainerExecInspect(ctx, id)
if err != nil {
return "", fmt.Errorf("failed to inspect exec process: %w", err)
}
results := dst.String()
// Style system output with color coding
styledOutput := fmt.Sprintf("%s%s%s%s", ansiColorSystemMsg, results, ansiColorReset, ansiLineTerminator)
_, err = t.tlp.PutMsg(ctx, database.TermlogTypeStdout, styledOutput, t.containerID, t.taskID, t.subtaskID)
if err != nil {
return "", fmt.Errorf("failed to put terminal log (stdout): %w", err)
}
if results == "" {
results = "Command completed successfully with exit code 0. No output produced (silent success)"
}
return results, nil
}
func (t *terminal) ReadFile(ctx context.Context, flowID int64, path string) (string, error) {
if path == "" {
return "", fmt.Errorf("path is required and cannot be empty")
}
cwd := docker.WorkFolderPathInContainer
escapedPath := strings.ReplaceAll(path, "'", "'\"'\"'")
catCommand := fmt.Sprintf("cat '%s'", escapedPath)
// Format read file command with stylingView on GitHub (pinned to ea665308ba)
Solutions
- Check database connectivity and logs (Postgres health, connection pool settings)
- Verify the termlog table constraints/column sizes vs the output size (truncate large outputs before PutMsg)
- Sanitize non-UTF8 output before logging
- Retry the operation once the DB recovers — the command result itself was valid
Example fix
// before
_, err = t.tlp.PutMsg(ctx, database.TermlogTypeStdout, styledOutput, ...)
if err != nil { return "", fmt.Errorf("failed to put terminal log (stdout): %w", err) }
// after
styledOutput = truncateString(strings.ToValidUTF8(styledOutput, string(utf8.RuneError)), 10000)
_, err = t.tlp.PutMsg(ctx, database.TermlogTypeStdout, styledOutput, ...) Defensive patterns
Strategy: fallback
Validate before calling
// pre-flight DB check in deployment health routine
if err := db.PingContext(ctx); err != nil {
log.Warn("database unreachable; termlog writes will fail")
} Try / catch
out, err := term.ExecCommand(ctx, flowID, cmd, false)
if err != nil && strings.Contains(err.Error(), "failed to put terminal log") {
// command succeeded; only logging failed — treat output as usable with degraded audit
log.Warn("termlog stdout write failed", "err", err)
} Prevention
- Monitor PostgreSQL connectivity and pool saturation
- Cap/truncate command output before it reaches the termlog store
- Sanitize binary/non-UTF8 output
- Alert on termlog write failures to keep audit logs trustworthy
When it happens
Trigger: PutMsg(ctx, database.TermlogTypeStdout, styledOutput, ...) returns an error — typically the database write fails: DB connection lost, transaction/lock issues, or the storage layer rejects the (possibly large or invalid-UTF8) output payload.
Common situations: PostgreSQL outage or connection-pool exhaustion during heavy pentest activity; output exceeding a size limit in the termlog table; encoding issues in binary command output.
Related errors
- failed to put terminal log (read file cmd): %w
- failed to put terminal log (read file content): %w
- failed to put terminal log (stdin): %w
- failed to put terminal log (write file cmd): %w
- failed to create flow agent log: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/d432920345cfbc04.
Report an issue: GitHub.