{"record":{"id":"41e7943e649b9367","repo":"hashicorp/terraform","slug":"error-finding-remote-workspace-w","errorCode":null,"errorMessage":"error finding remote workspace: %w","messagePattern":"error finding remote workspace: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote/backend_context.go","lineNumber":102,"sourceCode":"\trootMod, configDiags := op.ConfigLoader.LoadRootModule(op.ConfigDir)\n\tdiags = diags.Append(configDiags)\n\tif configDiags.HasErrors() {\n\t\treturn nil, nil, diags\n\t}\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, rootMod.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\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] backend/remote: retrieving variables from workspace %s/%s (%s)\", remoteWorkspaceName, b.organization, remoteWorkspaceID)\n\t\t\ttfeVariables, err := b.client.Variables.ListAll(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}","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/remote/backend_context.go#L84-L120","documentation":"Thrown when b.getRemoteWorkspaceID(ctx, op.Workspace) fails while resolving variables for a non-AllowUnsetVariables operation. The backend needs the opaque workspace ID (not just the name) to request workspace variables via the TFE API; if the ID lookup fails, variable resolution cannot proceed.","triggerScenarios":"b.getRemoteWorkspaceID returns an error - typically because fetchWorkspace failed (workspace not found, no access) or the API call to read the workspace errored. Distinct from the later fetchWorkspace call, this is specifically the ID resolution for the variables endpoint.","commonSituations":"Workspace name/prefix wrong so the lookup misses; token lacks read access; workspace exists but in wrong org; transient API error during ID resolution; AllowUnsetVariables not set so the strict path is taken.","solutions":["Verify the workspace name and prefix resolve to an existing, accessible workspace.","Confirm the token's team has 'Read' access and 'Read Variables' permission on the workspace.","If variables are not required, consider setting AllowUnsetVariables to take the stubbed path that skips ID resolution.","Retry - transient API errors during ID lookup are common."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-check workspace ID resolution + variable read permission.\nfunc canReadVariables(ctx context.Context, b *Remote, ws string) error {\n    id, err := b.getRemoteWorkspaceID(ctx, ws)\n    if err != nil { return fmt.Errorf(\"cannot resolve workspace for variables: %w\", err) }\n    _, err = b.client.Workspaces.ReadVariables(ctx, id, nil)\n    return err\n}","typeGuard":null,"tryCatchPattern":"// If ID resolution is flaky, fall back to AllowUnsetVariables only when safe.\nif _, err := b.getRemoteWorkspaceID(ctx, op.Workspace); err != nil {\n    if op.AllowUnsetVariables { /* stub path, OK */ } else { return err }\n}","preventionTips":["Grant the token's team 'Read Variables' permission on all target workspaces.","Verify workspace name/prefix resolve correctly before relying on variable injection.","Use AllowUnsetVariables for plan-only contexts where variable stubbing is acceptable."],"tags":["backend","remote-backend","workspace","variables","workspace-id","permissions","go"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}