{"record":{"id":"31b879ef3a1cdeb8","repo":"vxcontrol/pentagi","slug":"invalid-subtaskstatus-s","errorCode":null,"errorMessage":"invalid SubtaskStatus: %s","messagePattern":"invalid SubtaskStatus: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/server/models/subtasks.go","lineNumber":34,"sourceCode":"\tSubtaskStatusFinished SubtaskStatus = \"finished\"\n\tSubtaskStatusFailed   SubtaskStatus = \"failed\"\n)\n\nfunc (s SubtaskStatus) String() string {\n\treturn string(s)\n}\n\n// Valid is function to control input/output data\nfunc (s SubtaskStatus) Valid() error {\n\tswitch s {\n\tcase SubtaskStatusCreated,\n\t\tSubtaskStatusRunning,\n\t\tSubtaskStatusWaiting,\n\t\tSubtaskStatusFinished,\n\t\tSubtaskStatusFailed:\n\t\treturn nil\n\tdefault:\n\t\treturn fmt.Errorf(\"invalid SubtaskStatus: %s\", s)\n\t}\n}\n\n// Validate is function to use callback to control input/output data\nfunc (s SubtaskStatus) Validate(db *gorm.DB) {\n\tif err := s.Valid(); err != nil {\n\t\tdb.AddError(err)\n\t}\n}\n\n// Subtask is model to contain subtask information\n// nolint:lll\ntype Subtask struct {\n\tID          uint64        `form:\"id\" json:\"id\" validate:\"min=0,numeric\" gorm:\"type:BIGINT;NOT NULL;PRIMARY_KEY;AUTO_INCREMENT\"`\n\tStatus      SubtaskStatus `form:\"status\" json:\"status\" validate:\"valid,required\" gorm:\"type:SUBTASK_STATUS;NOT NULL;default:'created'\"`\n\tTitle       string        `form:\"title\" json:\"title\" validate:\"required\" gorm:\"type:TEXT;NOT NULL\"`\n\tDescription string        `form:\"description\" json:\"description\" validate:\"required\" gorm:\"type:TEXT;NOT NULL\"`\n\tContext     string        `form:\"context\" json:\"context\" validate:\"omitempty\" gorm:\"type:TEXT;NOT NULL;default:''\"`","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/server/models/subtasks.go#L16-L52","documentation":"SubtaskStatus is the lifecycle enum for a flow subtask: created, running, waiting, finished, failed. SubtaskStatus.Valid() returns this error for any other value, and the GORM Validate callback runs it on save, so a Subtask with a bad status cannot be persisted.","triggerScenarios":"Setting Subtask.Status from a state-machine transition that emits an out-of-whitelist string (e.g. 'completed' instead of 'finished', 'in_progress' instead of 'running'); accepting a status from an API payload without normalization; loading legacy rows with pre-rename status values.","commonSituations":"Deviations from the standard lifecycle names when integrating external tooling that drives subtask state; frontend shorthand ('done' vs 'finished'); SQL data fixes that wrote arbitrary statuses directly into the SUBTASK_STATUS column.","solutions":["Correct the value to one of: created, running, waiting, finished, failed (constants in backend/pkg/server/models/subtasks.go lines 12-18).","Use the models.SubtaskStatus* constants for all transitions instead of raw strings.","Normalize incoming API status strings (e.g. map 'completed'→'finished') before building the model, or call Valid() early and return a 400.","Fix any bad rows with a data migration before subsequent GORM updates fail."],"exampleFix":"// before\nsub := models.Subtask{Status: models.SubtaskStatus(\"completed\")}\n// after\nsub := models.Subtask{Status: models.SubtaskStatusFinished} // \"finished\"","handlingStrategy":"validation","validationCode":"func isValidSubtaskStatus(v string) bool {\n\tswitch models.SubtaskStatus(v) {\n\tcase models.SubtaskStatusCreated, models.SubtaskStatusRunning,\n\t\tmodels.SubtaskStatusWaiting, models.SubtaskStatusFinished,\n\t\tmodels.SubtaskStatusFailed:\n\t\treturn true\n\t}\n\treturn false\n}","typeGuard":"func asSubtaskStatus(v string) (models.SubtaskStatus, bool) {\n\ts := models.SubtaskStatus(v)\n\treturn s, s.Valid() == nil\n}","tryCatchPattern":"if err := status.Valid(); err != nil {\n\treturn fmt.Errorf(\"illegal subtask transition to %q: %w\", status, err)\n}","preventionTips":["Model subtask transitions as functions over SubtaskStatus constants, not free-form strings.","Normalize external status vocabularies ('completed' → finished) at the ingestion point.","Add a whitelist unit test covering every constant.","Keep the SUBTASK_STATUS Postgres enum aligned with the Go enum when extending."],"tags":["go","enum-validation","state-machine","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"}