vxcontrol/pentagi · warning
input must not be empty
Error message
input must not be empty
What it means
submit_flow_input parsed successfully but action.Input was an empty string, so the tool rejects the call before touching the database. Submitting empty input is meaningless — the tool exists to feed new instructions/data into a running flow — and this is an explicit domain validation rather than a JSON error.
Source
Thrown at backend/pkg/tools/flow_manager.go:703
func NewSubmitFlowInputTool(flowID int64, db database.Querier, handler func(ctx context.Context, input string) error) *submitFlowInputTool {
return &submitFlowInputTool{
flowID: flowID,
db: db,
handler: handler,
pollInterval: taskReadyPollInterval,
pollTimeout: taskReadyPollTimeout,
}
}
func (t *submitFlowInputTool) Handle(ctx context.Context, name string, args json.RawMessage) (string, error) {
var action SubmitFlowInputAction
if err := json.Unmarshal(args, &action); err != nil {
return "", fmt.Errorf("failed to parse %s args: %w", SubmitFlowInputToolName, err)
}
if action.Input == "" {
return "", fmt.Errorf("input must not be empty")
}
tasks, err := t.db.GetFlowTasks(ctx, t.flowID)
if err != nil {
return "", fmt.Errorf("failed to check flow status: %w", err)
}
for _, task := range tasks {
if task.Status == database.TaskStatusRunning {
return fmt.Sprintf(
"Cannot submit input: task %q (ID: %d) is currently running. "+
"Call %s first to stop the current execution, then retry %s. "+
"Use %s to confirm the flow reaches 'waiting' state before retrying",
task.Title, task.ID, StopFlowToolName, SubmitFlowInputToolName, GetFlowStatusToolName,
), nil
}
}
View on GitHub (pinned to ea665308ba)
Solutions
- Provide a non-empty input string: {"input": "<actual instruction or data>"}.
- Trim/validate the input at the call site before invoking the tool.
- Fix upstream interpolation — check the variable feeding input is populated.
- If input is optional, use a different flow-control tool instead of submitting empty input.
Example fix
// before await submitFlowInput(flowId, ''); // after const input = userText.trim(); if (input) await submitFlowInput(flowId, input);
Defensive patterns
Strategy: validation
Validate before calling
function validateSubmitInput(input: string): string {
const trimmed = input.trim();
if (!trimmed) throw new Error('input must not be empty');
return trimmed;
}
// call only after validation passes Type guard
function hasNonEmptyInput(v: unknown): v is { input: string } {
return typeof v === 'object' && v !== null &&
typeof (v as any).input === 'string' && (v as any).input.length > 0;
} Try / catch
try {
await tool.call('submit_flow_input', { input });
} catch (err) {
if (String(err).includes('input must not be empty')) {
// prompt user / regenerate a non-empty instruction
}
} Prevention
- Trim and check input before every submit_flow_input call
- Guard against empty variable interpolation feeding input
- Require the field in UI forms before enabling submit
- Use a different flow-control tool when there is nothing to submit
When it happens
Trigger: Calling submit_flow_input with {"input": ""}, {"input": " "} is allowed only if not trimmed (empty string exactly), or with the input field omitted after a successful unmarshal into the zero-value struct (e.g. args = {}).
Common situations: LLM generates an empty input placeholder; a caller builds args dynamically from a variable that was empty; a UI form allowed submission without filling the field; variable interpolation produced an empty string.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- invalid blob hash %q
- path must not be empty
- file name is required
- failed to parse %s args: %w
- failed to parse stop_flow args: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/d1ea7aff50137c6c.
Report an issue: GitHub.