{"record":{"id":"22d2f9cf2a9d33ac","repo":"pulumi/pulumi","slug":"unable-to-unmarshal-whoamidetailedinfo-w","errorCode":null,"errorMessage":"unable to unmarshal WhoAmIDetailedInfo: %w","messagePattern":"unable to unmarshal WhoAmIDetailedInfo: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdk/go/auto/local_workspace.go","lineNumber":560,"sourceCode":"\t\treturn \"\", newAutoError(fmt.Errorf(\"could not determine authenticated user: %w\", err), stdout, stderr, errCode)\n\t}\n\treturn strings.TrimSpace(stdout), nil\n}\n\n// WhoAmIDetails returns detailed information about the currently\n// logged-in Pulumi identity.\nfunc (l *LocalWorkspace) WhoAmIDetails(ctx context.Context) (WhoAmIResult, error) {\n\t// 3.58 added the --json flag (https://github.com/pulumi/pulumi/releases/tag/v3.58.0)\n\tif l.pulumiCommand.Version().GTE(semver.Version{Major: 3, Minor: 58}) {\n\t\tvar whoAmIDetailedInfo WhoAmIResult\n\t\tstdout, stderr, errCode, err := l.runPulumiCmdSync(ctx, \"whoami\", \"--json\")\n\t\tif err != nil {\n\t\t\treturn whoAmIDetailedInfo, newAutoError(\n\t\t\t\tfmt.Errorf(\"could not retrieve WhoAmIDetailedInfo: %w\", err), stdout, stderr, errCode)\n\t\t}\n\t\terr = json.Unmarshal([]byte(stdout), &whoAmIDetailedInfo)\n\t\tif err != nil {\n\t\t\treturn whoAmIDetailedInfo, fmt.Errorf(\"unable to unmarshal WhoAmIDetailedInfo: %w\", err)\n\t\t}\n\t\treturn whoAmIDetailedInfo, nil\n\t}\n\n\tstdout, stderr, errCode, err := l.runPulumiCmdSync(ctx, \"whoami\")\n\tif err != nil {\n\t\treturn WhoAmIResult{}, newAutoError(\n\t\t\tfmt.Errorf(\"could not determine authenticated user: %w\", err), stdout, stderr, errCode)\n\t}\n\treturn WhoAmIResult{User: strings.TrimSpace(stdout)}, nil\n}\n\n// OrgGetDefault returns the default organization for the current backend.\nfunc (l *LocalWorkspace) OrgGetDefault(ctx context.Context) (string, error) {\n\tbo := l.cliBaseOptions()\n\tresult, err := l.cliAPI.OrgGetDefault(ctx, func(o *optorggetdefault.Options) {\n\t\to.Cwd = bo.Cwd\n\t\to.AdditionalEnv = bo.AdditionalEnv","sourceCodeStart":542,"sourceCodeEnd":578,"githubUrl":"https://github.com/pulumi/pulumi/blob/793f7b2e160db4321fb7fb6b0607461e01cb251e/sdk/go/auto/local_workspace.go#L542-L578","documentation":"Thrown by LocalWorkspace.WhoAmIDetails when `pulumi whoami --json` succeeds but its stdout cannot be unmarshaled into WhoAmIResult. Means the CLI produced non-JSON or schema-incompatible output — typically a CLI older/newer than the struct expects, or extra text polluting stdout.","triggerScenarios":"Calling WhoAmIDetails with a CLI >= 3.58.0 whose whoami --json output schema differs from WhoAmIResult (orgs/types added or renamed in later versions); stdout polluted by login prompts or update notices.","commonSituations":"Very new CLIs adding fields handled fine, but breaking renames break parsing; old bundled CLIs emitting plain text despite the flag; wrapper scripts printing banners before JSON.","solutions":["Pin/upgrade the workspace's PulumiCommand to a CLI version whose whoami --json schema matches the SDK's WhoAmIResult","Inspect the raw stdout captured in the error context and remove any non-JSON pollution (banners, exec wrappers)","Use WhoAmI(ctx) for just the username if full details are optional","Wrap with errors.As/Unwrap to log the json.Unmarshal detail and the CLI version for bug reports"],"exampleFix":"// before\ninfo, err := ws.WhoAmIDetails(ctx) // breaks with mismatched CLI\n// after\nv := ws.PulumiCommand.Version()\nif v.LT(semver.Version{Major: 3, Minor: 130}) {\n    return fmt.Errorf(\"upgrade pulumi CLI for compatible whoami --json output\")\n}\ninfo, err := ws.WhoAmIDetails(ctx)","handlingStrategy":"fallback","validationCode":"v := ws.PulumiCommand.Version()\nif v.GTE(semver.Version{Major: 3, Minor: 58}) && v.LT(semver.Version{Major: 3, Minor: 999}) {\n    // known-compatible band for whoami --json parsing\n    _ = v\n}","typeGuard":"func isJSONOutput(s string) bool {\n    return strings.HasPrefix(strings.TrimSpace(s), \"{\")\n}","tryCatchPattern":"info, err := ws.WhoAmIDetails(ctx)\nif err != nil && strings.Contains(err.Error(), \"unmarshal\") {\n    if user, uErr := ws.WhoAmI(ctx); uErr == nil {\n        info = auto.WhoAmIResult{User: user} // degrade gracefully\n    } else {\n        return err\n    }\n} else if err != nil {\n    return err\n}","preventionTips":["Pin a known-compatible CLI version via PulumiCommand","Capture and log raw stdout when unmarshal fails","Strip stdout pollution (login prompts, upgrade banners) from exec environments","Prefer WhoAmI when only the username is needed"],"tags":["go","automation-api","json","version-compat"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"793f7b2e160db4321fb7fb6b0607461e01cb251e","analyzedAt":"2026-08-31T09:36:43.099Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}