{"record":{"id":"e34d3a35d8783269","repo":"linshenkx/prompt-optimizer","slug":"invalid-edit-session","errorCode":null,"errorMessage":"Invalid edit session","messagePattern":"Invalid edit session","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ui/src/composables/model/useTextModelManager.ts","lineNumber":798,"sourceCode":"      isLoadingModelOptions.value = false\n    }\n  }\n\n  const resolveFormMetadata = (\n    providerId: string,\n    modelId: string,\n    existingConfig?: TextModelConfig\n  ) => resolveTextModelMetadata({\n    providerId,\n    modelId,\n    registry: textAdapterRegistry,\n    existingProviderMeta: existingConfig?.providerMeta,\n    existingModelMeta: existingConfig?.modelMeta\n  })\n\n  const updateExistingModel = async () => {\n    if (!form.value.originalId) {\n      throw new Error('Invalid edit session')\n    }\n\n    const existingConfig = await modelManager.getModel(form.value.originalId)\n    if (!existingConfig) {\n      throw new Error('Model not found')\n    }\n\n    const connectionConfig: TextConnectionConfig = {\n      baseURL: (form.value.connectionConfig.baseURL as string)?.trim() || existingConfig.connectionConfig?.baseURL,\n      ...form.value.connectionConfig\n    }\n\n    if (form.value.displayMaskedKey) {\n      if (form.value.originalApiKey) {\n        connectionConfig.apiKey = form.value.originalApiKey\n      } else {\n        delete connectionConfig.apiKey\n      }","sourceCodeStart":780,"sourceCodeEnd":816,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/ui/src/composables/model/useTextModelManager.ts#L780-L816","documentation":"updateExistingModel throws 'Invalid edit session' when form.value.originalId is falsy. The form was routed into the update path (editingModelId set) but the form state never captured the id of the model being edited, so there is nothing to update.","triggerScenarios":"saveForm() choosing the update branch because editingModelId is set, while form.originalId was cleared by resetFormState() or never set when the edit session started. Can also happen if the form object is replaced wholesale without preserving originalId.","commonSituations":"Form state reset mid-session (e.g. prepareForClone ran after an edit started); reactivity bug where form.value is reassigned and originalId is dropped; two dialogs sharing the same composable instance clobbering each other's state.","solutions":["When entering edit mode, always set form.value.originalId together with editingModelId","Avoid calling resetFormState() while an edit session is active, or make it clear originalId too and exit edit mode","Before save, assert editingModelId === form.originalId and restart the edit flow if not","If the state is inconsistent, fall back to createNewModel() path or re-open edit via the model id"],"exampleFix":"// before\nconst updateExistingModel = async () => {\n  if (!form.value.originalId) throw new Error('Invalid edit session')\n\n// after\nconst updateExistingModel = async () => {\n  if (!form.value.originalId) {\n    form.value.originalId = editingModelId.value\n  }\n  if (!form.value.originalId) throw new Error('Invalid edit session')","handlingStrategy":"validation","validationCode":"if (editingModelId.value && !form.value.originalId) {\n  form.value.originalId = editingModelId.value\n}\nif (!form.value.originalId) { /* treat as create, or abort */ }","typeGuard":"const hasEditSession = (f: { originalId?: string | null }): f is { originalId: string } =>\n  typeof f.originalId === 'string' && f.originalId.length > 0","tryCatchPattern":"try { await saveForm() } catch (e) { if (String(e?.message) === 'Invalid edit session') { resetFormState(); notify('Edit session expired, please retry') } else throw e }","preventionTips":["Set originalId and editingModelId atomically when entering edit mode","Never call resetFormState() during an active edit session without exiting edit mode","Assert originalId truthy before enabling save in edit mode"],"tags":["form-state","edit-session","state-validation"],"backgroundTag":"invalid-session-state","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}