{"record":{"id":"3d3923316820662e","repo":"nektos/act","slug":"invalid-step-status-q","errorCode":null,"errorMessage":"invalid step status %q","messagePattern":"invalid step status %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/step_result.go","lineNumber":31,"sourceCode":"var stepStatusStrings = [...]string{\n\t\"success\",\n\t\"failure\",\n\t\"skipped\",\n}\n\nfunc (s stepStatus) MarshalText() ([]byte, error) {\n\treturn []byte(s.String()), nil\n}\n\nfunc (s *stepStatus) UnmarshalText(b []byte) error {\n\tstr := string(b)\n\tfor i, name := range stepStatusStrings {\n\t\tif name == str {\n\t\t\t*s = stepStatus(i)\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn fmt.Errorf(\"invalid step status %q\", str)\n}\n\nfunc (s stepStatus) String() string {\n\tif int(s) >= len(stepStatusStrings) {\n\t\treturn \"\"\n\t}\n\treturn stepStatusStrings[s]\n}\n\ntype StepResult struct {\n\tOutputs    map[string]string `json:\"outputs\"`\n\tConclusion stepStatus        `json:\"conclusion\"`\n\tOutcome    stepStatus        `json:\"outcome\"`\n}\n","sourceCodeStart":13,"sourceCodeEnd":46,"githubUrl":"https://github.com/nektos/act/blob/4f411281417e88660bea1c1a1749aa71ae0bd60f/pkg/model/step_result.go#L13-L46","documentation":"stepStatus.UnmarshalText accepts only the strings \"success\", \"failure\", and \"skipped\" (the only values in stepStatusStrings). Any other string while decoding a StepResult's Conclusion/Outcome from JSON — e.g. \"cancelled\" — produces this error. Note that \"cancelled\" is a valid GitHub conclusion but is NOT in this enum.","triggerScenarios":"Decoding persisted or externally produced step-result JSON whose conclusion is \"cancelled\", \"neutral\", or any casing/typo variant; round-tripping results between act versions or from the GitHub API into model.StepResult.","commonSituations":"Consuming act as a library and unmarshalling GitHub Actions API step data; fixtures copied from GitHub UI that use \"cancelled\"; JSON with \"Success\" (capitalized).","solutions":["Map external conclusions onto the three supported values before decoding: cancelled→skipped, neutral→success (or skip the record).","Fix the JSON source to emit only success|failure|skipped exactly lowercase.","If you need cancelled semantics, model it at a higher level rather than in model.StepResult."],"exampleFix":"// before\nvar r model.StepResult\njson.Unmarshal(data, &r) // data has \"cancelled\"\n// after\nallowed := map[string]bool{\"success\": true, \"failure\": true, \"skipped\": true}\nif !allowed[raw] {\n    raw = \"skipped\"\n}","handlingStrategy":"validation","validationCode":"var valid = map[string]bool{\"success\": true, \"failure\": true, \"skipped\": true}\nif s, ok := raw[\"conclusion\"].(string); ok && !valid[s] {\n    raw[\"conclusion\"] = \"skipped\" // normalize external conclusions like \"cancelled\"\n}","typeGuard":"func isKnownStepStatus(s string) bool {\n    switch s {\n    case \"success\", \"failure\", \"skipped\":\n        return true\n    }\n    return false\n}","tryCatchPattern":"var r model.StepResult\nif err := json.Unmarshal(data, &r); err != nil {\n    if strings.Contains(err.Error(), \"invalid step status\") {\n        // normalize the conclusion field and retry once\n    }\n}","preventionTips":["Only persist the three canonical lowercase values when serializing step results.","Translate GitHub API conclusions (cancelled, neutral, timed_out) at your integration boundary.","Pin act versions when round-tripping result JSON between systems."],"tags":["step-result","json","enum","unmarshal"],"backgroundTag":null,"analyzedSha":"4f411281417e88660bea1c1a1749aa71ae0bd60f","analyzedAt":"2026-08-15T09:19:46.307Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}