{"record":{"id":"3270f407a070ddc6","repo":"opentofu/opentofu","slug":"error-finding-remote-workspace-w-3270f4","errorCode":null,"errorMessage":"error finding remote workspace: %w","messagePattern":"error finding remote workspace: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cloud/backend_context.go","lineNumber":109,"sourceCode":"\tdiags = diags.Append(configDiags)\n\tif configDiags.HasErrors() {\n\t\treturn nil, nil, diags\n\t}\n\tret.Config = config\n\n\tif op.AllowUnsetVariables {\n\t\t// If we're not going to use the variables in an operation we'll be\n\t\t// more lax about them, stubbing out any unset ones as unknown.\n\t\t// This gives us enough information to produce a consistent context,\n\t\t// but not enough information to run a real operation (plan, apply, etc)\n\t\tret.PlanOpts.SetVariables = stubAllVariables(op.Variables, config.Module.Variables)\n\t} else {\n\t\t// The underlying API expects us to use the opaque workspace id to request\n\t\t// variables, so we'll need to look that up using our organization name\n\t\t// and workspace name.\n\t\tremoteWorkspaceID, err := b.getRemoteWorkspaceID(context.Background(), op.Workspace)\n\t\tif err != nil {\n\t\t\tdiags = diags.Append(fmt.Errorf(\"error finding remote workspace: %w\", err))\n\t\t\treturn nil, nil, diags\n\t\t}\n\t\tw, err := b.fetchWorkspace(context.Background(), b.organization, op.Workspace)\n\t\tif err != nil {\n\t\t\tdiags = diags.Append(fmt.Errorf(\"error loading workspace: %w\", err))\n\t\t\treturn nil, nil, diags\n\t\t}\n\n\t\tif isLocalExecutionMode(w.ExecutionMode) {\n\t\t\tlog.Printf(\"[TRACE] skipping retrieving variables from workspace %s/%s (%s), workspace is in Local Execution mode\", remoteWorkspaceName, b.organization, remoteWorkspaceID)\n\t\t} else {\n\t\t\tlog.Printf(\"[TRACE] cloud: retrieving variables from workspace %s/%s (%s)\", remoteWorkspaceName, b.organization, remoteWorkspaceID)\n\t\t\ttfeVariables, err := b.client.Variables.List(context.Background(), remoteWorkspaceID, nil)\n\t\t\tif err != nil && err != tfe.ErrResourceNotFound {\n\t\t\t\tdiags = diags.Append(fmt.Errorf(\"error loading variables: %w\", err))\n\t\t\t\treturn nil, nil, diags\n\t\t\t}\n","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/opentofu/opentofu/blob/3561785c48c1ce615e7c50261bd351f26053efa2/internal/cloud/backend_context.go#L91-L127","documentation":"Appended by Cloud.LocalRun (internal/cloud/backend_context.go:109) when b.getRemoteWorkspaceID fails while resolving the opaque workspace ID needed to list workspace variables (only on the non-AllowUnsetVariables path). getRemoteWorkspaceID performs a Workspaces.Read, so this wraps the same failures as fetchWorkspace: 404 (missing workspace or invisible to token), auth, network.","triggerScenarios":"Workspaces.Read during variable resolution returns tfe.ErrResourceNotFound, 401/403, or transport errors - e.g. workspace deleted between the earlier StateMgr step and here, or token without read access to that workspace.","commonSituations":"Workspace renamed/deleted mid-pipeline; wrong TF_WORKSPACE for the mapped environment; token team removed from the workspace between runs.","solutions":["Verify the workspace still exists and the token can read it (same checks as the 'workspace not found' error, backend.go:1126).","Re-run; transient mid-run 404s from eventual consistency usually clear.","Correct workspace selection (tags mapping, TF_WORKSPACE) before planning."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"// Confirm workspace resolvable before LocalRun's variable phase\nif _, err := client.Workspaces.Read(ctx, org, op.Workspace); err != nil {\n    return fmt.Errorf(\"workspace %s unreadable (%w) - fix name/token first\", op.Workspace, err)\n}","typeGuard":"func isRemoteWorkspaceLookupFailure(err error) bool {\n    return strings.HasPrefix(err.Error(), \"error finding remote workspace\")\n}","tryCatchPattern":"_, _, diags := b.LocalRun(ctx, stopCtx, op)\nif isRemoteWorkspaceLookupFailure(diags.Err()) {\n    // wrapped cause is a fetchWorkspace-style error: 404 vs auth vs network decides the fix\n}","preventionTips":["Validate TF_WORKSPACE and tag mapping in a pre-flight step of pipelines.","Avoid deleting/renaming workspaces while pipelines may be mid-run; use tombstone workspaces instead.","Reuse the same identity checks as fetchWorkspace errors (team membership, org spelling)."],"tags":["cloud-backend","workspace","variables","not-found"],"backgroundTag":null,"analyzedSha":"3561785c48c1ce615e7c50261bd351f26053efa2","analyzedAt":"2026-08-15T23:27:16.226Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}