{"record":{"id":"cd2825437241f6f8","repo":"GoogleContainerTools/skaffold","slug":"unknown-phase-v-not-found-in-handler-state-cd2825","errorCode":null,"errorMessage":"unknown Phase %v not found in handler state","messagePattern":"unknown Phase (.+?) not found in handler state","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/event/v2/state.go","lineNumber":167,"sourceCode":"\thandler.setState(newState)\n}\n\nfunc UpdateStateAutoSyncTrigger(t bool) {\n\tnewState := handler.getState()\n\tnewState.FileSyncState.AutoTrigger = t\n\thandler.setState(newState)\n}\n\nfunc AutoTriggerDiff(phase constants.Phase, val bool) (bool, error) {\n\tswitch phase {\n\tcase constants.Build:\n\t\treturn val != handler.getState().BuildState.AutoTrigger, nil\n\tcase constants.Sync:\n\t\treturn val != handler.getState().FileSyncState.AutoTrigger, nil\n\tcase constants.Deploy:\n\t\treturn val != handler.getState().DeployState.AutoTrigger, nil\n\tdefault:\n\t\treturn false, fmt.Errorf(\"unknown Phase %v not found in handler state\", phase)\n\t}\n}\n","sourceCodeStart":149,"sourceCodeEnd":170,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/event/v2/state.go#L149-L170","documentation":"AutoTriggerDiff compares a desired auto-trigger value against handler state for a given phase (Build/Sync/Deploy). If the phase argument is not one of the constants the state machine tracks, the switch's default branch returns this error. It signals a programming/API misuse: a Phase value that does not exist in the handler's state.","triggerScenarios":"Calling AutoTriggerDiff with a phase string that is not constants.Build, constants.Sync, or constants.Deploy — e.g. constants.Init, constants.DevLoop, an empty string, a typo, or a phase added in a newer version but not handled here.","commonSituations":"Wiring the auto-trigger UI/API to a new skaffold Phase without updating AutoTriggerDiff; comparing against an unexported/renamed constant after an upgrade; passing user-supplied phase names without validation.","solutions":["Pass only constants.Build, constants.Sync, or constants.Deploy to AutoTriggerDiff.","Add a case for the new Phase constant to AutoTriggerDiff if you genuinely added a new phase.","Validate/whitelist the phase value before calling, returning a clear error to the caller."],"exampleFix":"// before\nsame, err := event.AutoTriggerDiff(constants.Test, true)\n// after\nif phase != constants.Build && phase != constants.Sync && phase != constants.Deploy {\n    return fmt.Errorf(\"unsupported phase %q for auto-trigger\", phase)\n}\nsame, err := event.AutoTriggerDiff(phase, true)","handlingStrategy":"validation","validationCode":"func isValidPhase(phase constants.Phase) bool {\n    switch phase {\n    case constants.Build, constants.Sync, constants.Deploy:\n        return true\n    }\n    return false\n}\n// call only if isValidPhase(phase)","typeGuard":"func isTriggerablePhase(phase constants.Phase) bool {\n    switch phase {\n    case constants.Build, constants.Sync, constants.Deploy:\n        return true\n    default:\n        return false\n    }\n}","tryCatchPattern":"same, err := event.AutoTriggerDiff(phase, desired)\nif err != nil {\n    if strings.Contains(err.Error(), \"unknown Phase\") {\n        return fmt.Errorf(\"phase %q does not support auto-trigger: %w\", phase, err)\n    }\n    return err\n}","preventionTips":["Restrict auto-trigger calls to constants.Build/Sync/Deploy","Never pass user-supplied strings cast to Phase without whitelisting","Add a test enumerating all Phase constants and their AutoTriggerDiff support when adding phases"],"tags":["state-management","api-misuse","events"],"backgroundTag":"invalid-enum-value","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}