{"record":{"id":"82dfe0f3644dc6e3","repo":"GoogleContainerTools/skaffold","slug":"configuration-changed","errorCode":null,"errorMessage":"configuration changed","messagePattern":"configuration changed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"pkg/skaffold/runner/runner.go","lineNumber":41,"sourceCode":"\n\t\"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/build\"\n\t\"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/build/cache\"\n\t\"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/deploy\"\n\t\"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/deploy/label\"\n\t\"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/filemon\"\n\t\"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/graph\"\n\t\"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/kubernetes/manifest\"\n\t\"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/platform\"\n\t\"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/render/renderer\"\n\t\"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/runner/runcontext\"\n\t\"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/schema/latest\"\n\t\"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/schema/util\"\n\t\"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/test\"\n\t\"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/verify\"\n)\n\n// ErrorConfigurationChanged is a special error that's returned when the skaffold configuration was changed.\nvar ErrorConfigurationChanged = errors.New(\"configuration changed\")\n\n// Runner is responsible for running the skaffold build, test and deploy config.\ntype Runner interface {\n\tApply(context.Context, io.Writer) error\n\tApplyDefaultRepo(tag string) (string, error)\n\tBuild(context.Context, io.Writer, []*latest.Artifact) ([]graph.Artifact, error)\n\tCleanup(context.Context, io.Writer, bool, manifest.ManifestListByConfig, string) error\n\tDev(context.Context, io.Writer, []*latest.Artifact) error\n\t// Deploy and DeployAndLog: Do they need the `graph.Artifact` and could use render output.\n\tDeploy(context.Context, io.Writer, []graph.Artifact, manifest.ManifestListByConfig) error\n\tDeployAndLog(context.Context, io.Writer, []graph.Artifact, manifest.ManifestListByConfig) error\n\tGeneratePipeline(context.Context, io.Writer, []util.VersionedConfig, []string, string) error\n\tHasBuilt() bool\n\tDeployManifests() manifest.ManifestListByConfig\n\tPrune(context.Context, io.Writer) error\n\n\tRender(ctx context.Context, out io.Writer, builds []graph.Artifact, offline bool) (manifest.ManifestListByConfig, error)\n\tTest(context.Context, io.Writer, []graph.Artifact) error","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/runner/runner.go#L23-L59","documentation":"ErrorConfigurationChanged is a sentinel error (errors.Is-comparable) returned by the dev loop when skaffold detects that skaffold.yaml changed on disk. It is not a failure: cmd/dev.go catches it with errors.Is and restarts the dev cycle with reloaded configuration instead of exiting.","triggerScenarios":"Editing skaffold.yaml while `skaffold dev` is running; runDev/doDev returns this sentinel so the watcher loop can reload the schema and start a new cycle.","commonSituations":"Hot-reloading configuration during development: adding a profile, changing build args, or toggling port-forwards while a dev session is active. Also seen in tests simulating config reload cycles.","solutions":["No fix needed — save your skaffold.yaml changes and let skaffold restart the dev loop automatically.","If it surfaces as a terminating error in your own code, compare with errors.Is(err, runner.ErrorConfigurationChanged) and handle it as a restart signal, not a failure."],"exampleFix":"// before\nif err != nil {\n    return err\n}\n// after\nif err != nil {\n    if errors.Is(err, runner.ErrorConfigurationChanged) {\n        return nil // restart dev cycle with new config\n    }\n    return err\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func isConfigChanged(err error) bool { return errors.Is(err, runner.ErrorConfigurationChanged) }","tryCatchPattern":"if err := runner.Dev(ctx, out, []namespacedImage{}); err != nil {\n    if errors.Is(err, runner.ErrorConfigurationChanged) {\n        return nil // expected: restart dev loop with reloaded config\n    }\n    return err\n}","preventionTips":["Treat this sentinel as control flow, never as a fatal error — always compare with errors.Is.","Avoid wrapping the error with %v/%s (use %w) so errors.Is keeps working.","In tests, return this sentinel deliberately to exercise the config-reload path."],"tags":["dev-loop","config-reload","sentinel-error"],"backgroundTag":"config-changed-reload","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"}