{"record":{"id":"590d8448f6ddf8b7","repo":"stablyai/orca","slug":"failed-to-save-quick-command","errorCode":null,"errorMessage":"Failed to save quick command","messagePattern":"Failed to save quick command","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mobile/src/session/use-quick-commands.ts","lineNumber":196,"sourceCode":"        id: mutationContext.nextMutationId + 1,\n        mutation: commandMutation\n      }\n      mutationContext.nextMutationId = mutation.id\n      mutationContext.pending.push(mutation)\n      const optimistic = applyTerminalQuickCommandMutation(commandsRef.current, commandMutation)\n      commandsRef.current = optimistic\n      setCommands(optimistic)\n      setError(null)\n\n      const send = async (): Promise<boolean> => {\n        let succeeded = false\n        let failureMessage: string | null = null\n        try {\n          const response = await client.sendRequest('settings.updateTerminalQuickCommands', {\n            mutation: commandMutation\n          })\n          if (!response.ok) {\n            throw new Error(\n              (response as RpcFailure).error.message || 'Failed to save quick command'\n            )\n          }\n          const confirmed = readQuickCommands((response as RpcSuccess).result)\n          if (!confirmed) {\n            // Why: treating an invalid success payload as [] would let the next\n            // full-list mutation erase commands that still exist on the host.\n            throw new Error('Failed to save quick command')\n          }\n          mutationContext.confirmed = confirmed\n          succeeded = true\n          return true\n        } catch (err) {\n          failureMessage = err instanceof Error ? err.message : 'Failed to save quick command'\n          return false\n        } finally {\n          mutationContext.pending = mutationContext.pending.filter(\n            (pending) => pending.id !== mutation.id","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/mobile/src/session/use-quick-commands.ts#L178-L214","documentation":"Thrown inside the persist queue when `settings.updateTerminalQuickCommands` returns ok:false. The host's error.message is preferred; the literal is the fallback. (A sibling throw at line 204 covers the case where the success payload fails to parse - same message.) The queue rolls back optimistic state for the failed mutation.","triggerScenarios":"Host rejects the quick-command mutation - settings store write failure, schema validation, transport error, or relay cutover. Optimistic UI was already applied and will be rolled back to the last confirmed list.","commonSituations":"Editing/adding/deleting a quick command during a reconnect window; host settings file locked; mutation payload references a command id the host does not know; relay cutover mid-save.","solutions":["Retry the edit after reconnecting.","Reload quick commands (settings.getTerminalQuickCommands) to resync.","Check host settings store.","Avoid mutating during reconnect."],"exampleFix":"// before\nif (!response.ok) {\n  throw new Error((response as RpcFailure).error.message || 'Failed to save quick command')\n}\n// after\nif (!response.ok) {\n  throw new RpcMethodError('settings.updateTerminalQuickCommands', response.error)\n}","handlingStrategy":"try-catch","validationCode":"if (!client || connState !== 'connected') {\n  setError('Waiting for desktop...')\n  return false\n}","typeGuard":"function isRpcFailure(r: RpcResponse): r is RpcFailure {\n  return r.ok === false\n}","tryCatchPattern":"const ok = await persist(mutation)\nif (!ok) setError('Failed to save quick command - retry')","preventionTips":["Disable the save control until connected and the list is ready.","Reload the canonical list after a failed save.","Retry once on logical-client cutover (see loadQuickCommandsWithCutoverRetry).","Do not treat an unparseable success payload as [] - it would erase host commands."],"tags":["rpc","settings","quick-commands","mobile"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}