{"record":{"id":"d63660b487320d8b","repo":"kubernetes/kops","slug":"unexpected-path-type-t-for-q","errorCode":null,"errorMessage":"unexpected path type %T for %q","messagePattern":"unexpected path type %T for %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/resources/nodeup.go","lineNumber":432,"sourceCode":"\treturn b.CloudProvider == string(kops.CloudProviderAzure) && b.firstLocationWithScheme(\"azureblob://\") != \"\"\n}\n\n// ResolveS3Region resolves the bucket region because SigV4 requires it but s3:// URLs omit it.\nfunc (b *NodeUpScript) ResolveS3Region(ctx context.Context, vfsContext *vfs.VFSContext) error {\n\tif b.CloudProvider != string(kops.CloudProviderAWS) {\n\t\treturn nil\n\t}\n\tlocation := b.firstLocationWithScheme(\"s3://\")\n\tif location == \"\" {\n\t\treturn nil\n\t}\n\tp, err := vfsContext.BuildVfsPath(location)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"building path for %q: %w\", location, err)\n\t}\n\ts3Path, ok := p.(*vfs.S3Path)\n\tif !ok {\n\t\treturn fmt.Errorf(\"unexpected path type %T for %q\", p, location)\n\t}\n\tb.S3Region, err = s3Path.Region(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"getting the region of %q: %w\", location, err)\n\t}\n\tsupported, err := awsup.SupportsS3BootstrapEndpoint(ctx, b.S3Region)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !supported {\n\t\treturn fmt.Errorf(\"downloading nodeup from an s3:// URL is not supported in AWS region %q\", b.S3Region)\n\t}\n\treturn nil\n}\n\nfunc gzipBase64(data string) (string, error) {\n\tvar b bytes.Buffer\n\tgz := gzip.NewWriter(&b)","sourceCodeStart":414,"sourceCodeEnd":450,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/model/resources/nodeup.go#L414-L450","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use the default vfs.Context (or one with S3 registered) so s3:// resolves to *vfs.S3Path.","Check the %T in the message to see what type was actually returned and why.","In tests, either register an S3 path implementation or test ResolveS3Region with real S3 path construction.","Review any code that swaps vfsContext to ensure s3:// mappings are preserved."],"exampleFix":"// before\nvfsContext = vfs.NewContext() // custom context missing S3 handling in test\n// after\nvfsContext = vfs.Context{} // default context; s3:// resolves to *vfs.S3Path","handlingStrategy":"type-guard","validationCode":"p, err := vfsContext.BuildVfsPath(loc)\nif err != nil { return err }\nif _, ok := p.(*vfs.S3Path); !ok {\n    return fmt.Errorf(\"expected *vfs.S3Path, got %T\", p)\n}","typeGuard":"func isS3Path(p vfs.Path) bool { _, ok := p.(*vfs.S3Path); return ok }","tryCatchPattern":"if err := script.ResolveS3Region(ctx); err != nil {\n    if strings.Contains(err.Error(), \"unexpected path type\") {\n        return fmt.Errorf(\"vfs context does not resolve s3:// to S3Path: %w\", err)\n    }\n    return err\n}","preventionTips":["Never swap vfsContext for a memfs/mock in paths that resolve s3:// sources","Assert path types in tests that touch S3 region resolution","Keep VFS context setup identical between prod and integration-test code"],"tags":["s3","vfs","type-mismatch","nodeup"],"backgroundTag":"vfs-path-type-mismatch","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}