GoogleContainerTools/skaffold · error

yaml tag `filepath` needs struct field %q to be string or st

Error message

yaml tag `filepath` needs struct field %q to be string or string slice

What it means

Skaffold walks its config structs via reflection, and struct fields tagged `filepath:"true"` must hold a string or string slice so relative paths can be made absolute. If such a field holds any other kind (map, struct, int, etc.), the walker cannot process it and returns this error naming the field.

Source

Thrown at pkg/skaffold/tags/paths.go:89

						elem := v.Index(j)
						path := elem.String()
						if path == "" || filepath.IsAbs(path) {
							continue
						}
						elem.SetString(filepath.Join(base, path))
						log.Entry(context.TODO()).Tracef("setting absolute paths for config field %q index %d", f.Name, j)
					}
				case map[string]string:
					for _, key := range v.MapKeys() {
						path := v.MapIndex(key).String()
						if path == "" || filepath.IsAbs(path) {
							continue
						}
						v.SetMapIndex(key, reflect.ValueOf(filepath.Join(base, path)))
						log.Entry(context.TODO()).Tracef("setting absolute paths for config field %q key %q", f.Name, key.String())
					}
				default:
					return []error{fmt.Errorf("yaml tag `filepath` needs struct field %q to be string or string slice", f.Name)}
				}
				continue
			}

			if v.Kind() != reflect.Pointer {
				v = v.Addr()
			}
			if elemErrs := makeFilePathsAbsolute(v.Interface(), base); elemErrs != nil {
				errs = append(errs, elemErrs...)
			}
		}
		return errs
	case reflect.Slice:
		var errs []error
		for i := 0; i < parentStruct.Len(); i++ {
			elem := parentStruct.Index(i)
			if elem.Kind() != reflect.Pointer {
				elem = elem.Addr()

View on GitHub (pinned to a1189de023)

Solutions

  1. Change the field's type to string or []string
  2. Remove the `filepath` yaml tag if the field no longer holds paths
  3. For map-typed path fields, add an explicit map-handling branch in paths.go instead of the tag

Example fix

// before
type Config struct {
    Manifests map[string]string `yaml:"manifests" filepath:"true"`
}

// after
type Config struct {
    Manifests []string `yaml:"manifests" filepath:"true"`
}
Defensive patterns

Strategy: type-guard

Validate before calling

if v.Kind() != reflect.String && v.Kind() != reflect.Slice {
    return fmt.Errorf("field %q with filepath tag must be string or []string", f.Name)
}

Type guard

func isPathKind(v reflect.Value) bool {
    if v.Kind() == reflect.String { return true }
    return v.Kind() == reflect.Slice && v.Type().Elem().Kind() == reflect.String
}

Try / catch

if errs := tags.MakeFilePathsAbsolute(cfg, dir); len(errs) > 0 {
    for _, e := range errs {
        if strings.Contains(e.Error(), "needs struct field") {
            return fmt.Errorf("config struct bug, fix field type or remove filepath tag: %w", e)
        }
    }
}

Prevention

When it happens

Trigger: Running MakeFilePathsAbsolute over a config struct where a field with the yaml `filepath` tag is of a kind other than string or []string — typically a developer error when adding/changing a config field in the latest config package.

Common situations: Adding a new config field with the filepath tag but a composite type; changing an existing string filepath field to a map without removing the tag; third-party/embedded structs reusing the tag incorrectly.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/a4af6a74752bae16. Report an issue: GitHub.