{"record":{"id":"408ba1cf823f2129","repo":"vxcontrol/pentagi","slug":"invalid-flowstatus-s","errorCode":null,"errorMessage":"invalid FlowStatus: %s","messagePattern":"invalid FlowStatus: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/server/models/flows.go","lineNumber":36,"sourceCode":"\tFlowStatusFinished FlowStatus = \"finished\"\n\tFlowStatusFailed   FlowStatus = \"failed\"\n)\n\nfunc (s FlowStatus) String() string {\n\treturn string(s)\n}\n\n// Valid is function to control input/output data\nfunc (s FlowStatus) Valid() error {\n\tswitch s {\n\tcase FlowStatusCreated,\n\t\tFlowStatusRunning,\n\t\tFlowStatusWaiting,\n\t\tFlowStatusFinished,\n\t\tFlowStatusFailed:\n\t\treturn nil\n\tdefault:\n\t\treturn fmt.Errorf(\"invalid FlowStatus: %s\", s)\n\t}\n}\n\n// Validate is function to use callback to control input/output data\nfunc (s FlowStatus) Validate(db *gorm.DB) {\n\tif err := s.Valid(); err != nil {\n\t\tdb.AddError(err)\n\t}\n}\n\n// Flow is model to contain flow information\n// nolint:lll\ntype Flow struct {\n\tID                 uint64           `form:\"id\" json:\"id\" validate:\"min=0,numeric\" gorm:\"type:BIGINT;NOT NULL;PRIMARY_KEY;AUTO_INCREMENT\"`\n\tStatus             FlowStatus       `form:\"status\" json:\"status\" validate:\"valid,required\" gorm:\"type:FLOW_STATUS;NOT NULL;default:'created'\"`\n\tTitle              string           `form:\"title\" json:\"title\" validate:\"required\" gorm:\"type:TEXT;NOT NULL;default:'untitled'\"`\n\tModel              string           `form:\"model\" json:\"model\" validate:\"max=70,required\" gorm:\"type:TEXT;NOT NULL\"`\n\tModelProviderName  string           `form:\"model_provider_name\" json:\"model_provider_name\" validate:\"max=70,required\" gorm:\"type:TEXT;NOT NULL\"`","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/server/models/flows.go#L18-L54","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use one of the exact FlowStatus constants from flows.go (e.g. created/running/waiting/finished/failed).","Do not set status manually on flow creation unless the API expects it — let the backend initialize it.","Map foreign states to the nearest FlowStatus (e.g. completed -> finished, error -> failed).","Check exact casing and whitespace."],"exampleFix":"// before\n{\"status\": \"completed\"}\n// after\n{\"status\": \"finished\"}","handlingStrategy":"validation","validationCode":"const FLOW_STATUSES = [\"created\", \"running\", \"waiting\", \"finished\", \"failed\"] as const;\nfunction isValidFlowStatus(s: string): boolean {\n  return (FLOW_STATUSES as readonly string[]).includes(s);\n}\nif (!isValidFlowStatus(input.status)) throw new Error(`invalid FlowStatus: ${input.status}`);","typeGuard":"function isFlowStatus(v: unknown): v is \"created\" | \"running\" | \"waiting\" | \"finished\" | \"failed\" {\n  return [\"created\", \"running\", \"waiting\", \"finished\", \"failed\"].includes(v as string);\n}","tryCatchPattern":"try {\n  await api.createFlow({ ...payload });\n} catch (err) {\n  if (String(err).includes(\"invalid FlowStatus\")) {\n    // omit the status field and let the backend initialize the lifecycle\n    const { status, ...rest } = payload;\n    await api.createFlow(rest);\n  } else throw err;\n}","preventionTips":["Don't set status on flow creation — the backend owns the state machine's initial value.","Translate synonyms (completed/error/queued) to finished/failed/waiting before sending.","Mirror FlowStatus constants in a shared client enum instead of literals.","Add a zod enum to the flow-creation schema."],"tags":["validation","enum","flows","gorm"],"backgroundTag":"invalid-enum-value","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}