kubernetes/kops · error

unexpected path type %T for %q

Error message

unexpected path type %T for %q

What it means

After building the VFS path for the first s3:// source, ResolveS3Region asserts it is actually a *vfs.S3Path via a type assertion. If the vfs context resolved the location to a different path type (e.g. a local/memfs path because the VFS context is misconfigured), this error fires with the unexpected Go type in the message.

Source

Thrown at pkg/model/resources/nodeup.go:432

	return b.CloudProvider == string(kops.CloudProviderAzure) && b.firstLocationWithScheme("azureblob://") != ""
}

// ResolveS3Region resolves the bucket region because SigV4 requires it but s3:// URLs omit it.
func (b *NodeUpScript) ResolveS3Region(ctx context.Context, vfsContext *vfs.VFSContext) error {
	if b.CloudProvider != string(kops.CloudProviderAWS) {
		return nil
	}
	location := b.firstLocationWithScheme("s3://")
	if location == "" {
		return nil
	}
	p, err := vfsContext.BuildVfsPath(location)
	if err != nil {
		return fmt.Errorf("building path for %q: %w", location, err)
	}
	s3Path, ok := p.(*vfs.S3Path)
	if !ok {
		return fmt.Errorf("unexpected path type %T for %q", p, location)
	}
	b.S3Region, err = s3Path.Region(ctx)
	if err != nil {
		return fmt.Errorf("getting the region of %q: %w", location, err)
	}
	supported, err := awsup.SupportsS3BootstrapEndpoint(ctx, b.S3Region)
	if err != nil {
		return err
	}
	if !supported {
		return fmt.Errorf("downloading nodeup from an s3:// URL is not supported in AWS region %q", b.S3Region)
	}
	return nil
}

func gzipBase64(data string) (string, error) {
	var b bytes.Buffer
	gz := gzip.NewWriter(&b)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Use the default vfs.Context (or one with S3 registered) so s3:// resolves to *vfs.S3Path.
  2. Check the %T in the message to see what type was actually returned and why.
  3. In tests, either register an S3 path implementation or test ResolveS3Region with real S3 path construction.
  4. Review any code that swaps vfsContext to ensure s3:// mappings are preserved.

Example fix

// before
vfsContext = vfs.NewContext() // custom context missing S3 handling in test
// after
vfsContext = vfs.Context{} // default context; s3:// resolves to *vfs.S3Path
Defensive patterns

Strategy: type-guard

Validate before calling

p, err := vfsContext.BuildVfsPath(loc)
if err != nil { return err }
if _, ok := p.(*vfs.S3Path); !ok {
    return fmt.Errorf("expected *vfs.S3Path, got %T", p)
}

Type guard

func isS3Path(p vfs.Path) bool { _, ok := p.(*vfs.S3Path); return ok }

Try / catch

if err := script.ResolveS3Region(ctx); err != nil {
    if strings.Contains(err.Error(), "unexpected path type") {
        return fmt.Errorf("vfs context does not resolve s3:// to S3Path: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling ResolveS3Region when vfsContext.BuildVfsPath returns a non-S3Path for the s3:// location — typically because the VFS context was constructed with a custom/alternative path registry or a mock that maps s3:// to another filesystem.

Common situations: Tests injecting a memfs-backed VFS context while still using s3:// nodeup sources; custom builds that replaced the default vfs context; vfs context initialized without S3 support.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/d63660b487320d8b. Report an issue: GitHub.