vxcontrol/pentagi · error

invalid FlowStatus: %s

Error message

invalid FlowStatus: %s

What it means

FlowStatus.Valid() in backend/pkg/server/models/flows.go accepts only the FlowStatus lifecycle constants (running, waiting, finished, failed, plus the initial state defined above the excerpt). Any other value fails the GORM Validate callback. FlowStatus tracks the penetration-test workflow's state machine.

Source

Thrown at backend/pkg/server/models/flows.go:36

	FlowStatusFinished FlowStatus = "finished"
	FlowStatusFailed   FlowStatus = "failed"
)

func (s FlowStatus) String() string {
	return string(s)
}

// Valid is function to control input/output data
func (s FlowStatus) Valid() error {
	switch s {
	case FlowStatusCreated,
		FlowStatusRunning,
		FlowStatusWaiting,
		FlowStatusFinished,
		FlowStatusFailed:
		return nil
	default:
		return fmt.Errorf("invalid FlowStatus: %s", s)
	}
}

// Validate is function to use callback to control input/output data
func (s FlowStatus) Validate(db *gorm.DB) {
	if err := s.Valid(); err != nil {
		db.AddError(err)
	}
}

// Flow is model to contain flow information
// nolint:lll
type Flow struct {
	ID                 uint64           `form:"id" json:"id" validate:"min=0,numeric" gorm:"type:BIGINT;NOT NULL;PRIMARY_KEY;AUTO_INCREMENT"`
	Status             FlowStatus       `form:"status" json:"status" validate:"valid,required" gorm:"type:FLOW_STATUS;NOT NULL;default:'created'"`
	Title              string           `form:"title" json:"title" validate:"required" gorm:"type:TEXT;NOT NULL;default:'untitled'"`
	Model              string           `form:"model" json:"model" validate:"max=70,required" gorm:"type:TEXT;NOT NULL"`
	ModelProviderName  string           `form:"model_provider_name" json:"model_provider_name" validate:"max=70,required" gorm:"type:TEXT;NOT NULL"`

View on GitHub (pinned to ea665308ba)

Solutions

  1. Use one of the exact FlowStatus constants from flows.go (e.g. created/running/waiting/finished/failed).
  2. Do not set status manually on flow creation unless the API expects it — let the backend initialize it.
  3. Map foreign states to the nearest FlowStatus (e.g. completed -> finished, error -> failed).
  4. Check exact casing and whitespace.

Example fix

// before
{"status": "completed"}
// after
{"status": "finished"}
Defensive patterns

Strategy: validation

Validate before calling

const FLOW_STATUSES = ["created", "running", "waiting", "finished", "failed"] as const;
function isValidFlowStatus(s: string): boolean {
  return (FLOW_STATUSES as readonly string[]).includes(s);
}
if (!isValidFlowStatus(input.status)) throw new Error(`invalid FlowStatus: ${input.status}`);

Type guard

function isFlowStatus(v: unknown): v is "created" | "running" | "waiting" | "finished" | "failed" {
  return ["created", "running", "waiting", "finished", "failed"].includes(v as string);
}

Try / catch

try {
  await api.createFlow({ ...payload });
} catch (err) {
  if (String(err).includes("invalid FlowStatus")) {
    // omit the status field and let the backend initialize the lifecycle
    const { status, ...rest } = payload;
    await api.createFlow(rest);
  } else throw err;
}

Prevention

When it happens

Trigger: Creating a flow with status "pending", "queued", "completed", "error", or empty; updating flow status manually from client code or scripts; filtering the flow list by an unknown status.

Common situations: Client inventing status names instead of using the API's lifecycle; case mismatches ("Running"); copying status vocabulary from other entities (Container/Assistant); stale SDKs after a rename.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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