GoogleContainerTools/skaffold · error
watching files for artifact %q: %w
Error message
watching files for artifact %q: %w
What it means
Dev() registers build dependencies for each artifact with the file monitor via r.monitor.Register. If computing or registering the watch set for an artifact fails, Skaffold emits DEVINIT_REGISTER_BUILD_DEPS and aborts with 'watching files for artifact <image>'. The failure comes from the artifact's BuildDependencies() (e.g. enumerating source files) or the monitor's registration.
Source
Thrown at pkg/skaffold/runner/dev.go:406
func() ([]string, error) {
return r.sourceDependencies.TransitiveArtifactDependencies(ctx, artifact)
},
func(e filemon.Events) {
s, err := sync.NewItem(ctx, artifact, e, r.Builds, r.runCtx, len(g[artifact.ImageName]))
switch {
case err != nil:
log.Entry(ctx).Warnf("error adding dirty artifact to changeset: %s", err.Error())
case s != nil:
r.changeSet.AddResync(s)
default:
r.changeSet.AddRebuild(artifact)
}
},
); err != nil {
event.DevLoopFailedWithErrorCode(r.devIteration, proto.StatusCode_DEVINIT_REGISTER_BUILD_DEPS, err)
eventV2.TaskFailed(constants.DevLoop, err)
endTrace()
return fmt.Errorf("watching files for artifact %q: %w", artifact.ImageName, err)
}
}
}
// Watch test configuration
for i := range artifacts {
artifact := artifacts[i]
if err := r.monitor.Register(
func() ([]string, error) { return r.tester.TestDependencies(ctx, artifact) },
func(filemon.Events) { r.changeSet.AddRetest(artifact) },
); err != nil {
event.DevLoopFailedWithErrorCode(r.devIteration, proto.StatusCode_DEVINIT_REGISTER_TEST_DEPS, err)
eventV2.TaskFailed(constants.DevLoop, err)
endTrace()
return fmt.Errorf("watching test files: %w", err)
}
}
View on GitHub (pinned to a1189de023)
Solutions
- Fix the artifact path/globs in skaffold.yaml so the build context resolves
- Check the wrapped error for which file or directory is unreadable and restore permissions
- Raise inotify watch limits: `sysctl fs.inotify.max_user_watches=524288`
- Re-run `skaffold dev`
Example fix
// before (skaffold.yaml)
artifacts:
- image: app
context: ./src/app # directory removed
// after
artifacts:
- image: app
context: . Defensive patterns
Strategy: validation
Validate before calling
// verify every artifact build context resolves before dev
for _, a := range cfg.Build.Artifacts {
if _, err := os.Stat(a.Workspace); err != nil {
return fmt.Errorf("artifact %q workspace missing: %w", a.ImageName, err)
}
} Prevention
- Keep artifact contexts inside the repo and committed
- Check fs.inotify.max_user_watches on dev machines
- Avoid symlinks into unreadable directories
- Run `skaffold build` first to exercise dependency enumeration
When it happens
Trigger: `r.monitor.Register(artifact.Dependencies, ...)` (inside RegisterBuildDependencies) returns an error for a specific artifact.ImageName — typically when resolving the artifact's build context file list fails (unreadable directories, bad sync/workspace globs) or the watcher cannot be created.
Common situations: Build context directory deleted or unreadable (permissions); Dockerfile referenced by the artifact missing; file watcher limit (inotify watches) exhausted; a workspace path in skaffold.yaml points outside the repo.
Related errors
- watching test files: %w
- watching skaffold configuration %q: %w
- unable to start trigger: %w
- didn't sync any files
- executing build: %w
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/555f7437bf104e4d.
Report an issue: GitHub.