{"record":{"id":"2ac615c7c4e7c5c1","repo":"different-ai/openwork","slug":"app-error-connect-first","errorCode":"app.error_connect_first","errorMessage":"app.error_connect_first","messagePattern":"app\\.error_connect_first","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/app/src/react-app/domains/workspace/use-remote-workspace-connection-editor.ts","lineNumber":110,"sourceCode":"      try {\n        const displayName = fields.displayName?.trim() || null;\n        const directory = fields.directory?.trim() || null;\n        const openworkToken = fields.openworkToken?.trim() ?? \"\";\n        if (isDesktopRuntime()) {\n          await workspaceUpdateRemote({\n            workspaceId: id,\n            baseUrl,\n            openworkHostUrl: baseUrl,\n            openworkToken,\n            openworkClientToken: \"\",\n            openworkHostToken: \"\",\n            displayName,\n            directory,\n            remoteType: \"openwork\",\n          });\n          await onSaved(id);\n        } else {\n          if (!client) throw new Error(t(\"app.error_connect_first\"));\n          const connectionChanged = baseUrl !== (initialValues.openworkHostUrl?.trim() ?? \"\") ||\n            openworkToken !== (initialValues.openworkToken?.trim() ?? \"\") ||\n            directory !== (initialValues.directory?.trim() || null);\n          if (connectionChanged) {\n            const result = await client.createRemoteWorkspace({\n              baseUrl,\n              openworkHostUrl: baseUrl,\n              openworkToken: openworkToken || null,\n              displayName,\n              directory,\n              remoteType: \"openwork\",\n            });\n            await onSaved(result.activeId ?? id);\n          } else {\n            await client.updateWorkspaceDisplayName(id, displayName);\n            await onSaved(id);\n          }\n        }","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/app/src/react-app/domains/workspace/use-remote-workspace-connection-editor.ts#L92-L128","documentation":"Thrown by the remote workspace connection editor when saving an OpenWork-type connection without an established client. The hook only has a connected client after a successful connection check; if the form is in 'new/edit OpenWork connection' mode and `client` is still null, saving is rejected with 'app.error_connect_first' telling the user to test/connect first.","triggerScenarios":"Submitting the connection editor form with remoteType 'openwork' when the user has not run the connect/check step (or the check failed), so the `client` variable from the connection check is still undefined.","commonSituations":"User types a host URL and token but skips pressing the connect/test button; connection check failed silently (wrong token, unreachable URL); editing a connection and changing fields without re-validating.","solutions":["Run the connection check (connect/test) so a client is created before saving.","Verify the OpenWork host URL and token are correct if the check failed.","Ensure network access to the remote host; retry the connect step."],"exampleFix":"// before\nif (!client) throw new Error(t(\"app.error_connect_first\"));\n// after — auto-run the check instead of throwing\nlet activeClient = client;\nif (!activeClient) activeClient = await runConnectionCheck(baseUrl, openworkToken);\nconst connectionChanged = /* unchanged */;","handlingStrategy":"validation","validationCode":"const canSave = remoteType !== \"openwork\" || client != null;\nif (!canSave) { showHint(t(\"app.error_connect_first\")); return; }","typeGuard":"function hasClient(c: Client | null | undefined): c is Client {\n  return c != null;\n}","tryCatchPattern":"try {\n  await editor.save();\n} catch (error) {\n  if (error.message === t(\"app.error_connect_first\")) {\n    await editor.runConnectionCheck(); // recover by connecting\n  } else throw error;\n}","preventionTips":["Disable the save button until the connection check has succeeded.","Auto-run the connection check on blur of host/token fields.","Show inline validation state (untested / connected / failed)."],"tags":["validation","workspace","connection"],"backgroundTag":"connect-before-save","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}