{"record":{"id":"4fe01fe8dbd835aa","repo":"paperclipai/paperclip","slug":"workspace-commands-json-must-be-a-json-object","errorCode":null,"errorMessage":"Workspace commands JSON must be a JSON object.","messagePattern":"Workspace commands JSON must be a JSON object\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ui/src/pages/ExecutionWorkspaceDetail.tsx","lineNumber":319,"sourceCode":"  maybeAssign(\"cwd\");\n  maybeAssign(\"repoUrl\");\n  maybeAssign(\"baseRef\");\n  maybeAssign(\"branchName\");\n  maybeAssign(\"providerRef\");\n\n  const maybeAssignConfigText = (key: keyof Pick<WorkspaceFormState, \"provisionCommand\" | \"runtimeProvisionCommand\" | \"teardownCommand\" | \"cleanupCommand\">) => {\n    if (initialState[key] === nextState[key]) return;\n    configPatch[key] = normalizeText(nextState[key]);\n  };\n\n  maybeAssignConfigText(\"provisionCommand\");\n  maybeAssignConfigText(\"runtimeProvisionCommand\");\n  maybeAssignConfigText(\"teardownCommand\");\n  maybeAssignConfigText(\"cleanupCommand\");\n\n  if (initialState.inheritRuntime !== nextState.inheritRuntime || initialState.workspaceRuntime !== nextState.workspaceRuntime) {\n    const parsed = parseWorkspaceRuntimeJson(nextState.workspaceRuntime);\n    if (!parsed.ok) throw new Error(parsed.error);\n    configPatch.workspaceRuntime = nextState.inheritRuntime ? null : parsed.value;\n  }\n\n  if (Object.keys(configPatch).length > 0) {\n    patch.config = configPatch;\n  }\n\n  return patch;\n}\n\nfunction validateForm(form: WorkspaceFormState) {\n  const repoUrl = normalizeText(form.repoUrl);\n  if (repoUrl) {\n    try {\n      new URL(repoUrl);\n    } catch {\n      return \"Repo URL must be a valid URL.\";\n    }","sourceCodeStart":301,"sourceCodeEnd":337,"githubUrl":"https://github.com/paperclipai/paperclip/blob/a7e689b3c35347b529cb9f54c9b9a8575a3dcab6/ui/src/pages/ExecutionWorkspaceDetail.tsx#L301-L337","documentation":"Shape guard in buildWorkspacePatch: the workspace 'commands' field must serialize to a JSON object (record of command strings), but the parsed/entered value is an array, scalar, or malformed JSON. The patch build aborts so an invalid commands map is never sent to the workspace update API.","triggerScenarios":"Thrown at ui/src/pages/ExecutionWorkspaceDetail.tsx:313 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Enter a valid JSON object (e.g. {\"job\": {\"command\": \"...\"}}) for the workspace commands configuration."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"a7e689b3c35347b529cb9f54c9b9a8575a3dcab6","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}