{"record":{"id":"1c4475d46a7bd932","repo":"slopus/happy","slug":"metadata-version-mismatch","errorCode":null,"errorMessage":"Metadata version mismatch","messagePattern":"Metadata version mismatch","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/happy-cli/src/api/apiMachine.ts","lineNumber":394,"sourceCode":"        await backoff(async () => {\n            const updated = handler(this.machine.metadata);\n\n            const answer = await this.socket.emitWithAck('machine-update-metadata', {\n                machineId: this.machine.id,\n                metadata: encodeBase64(encrypt(this.machine.encryptionKey, this.machine.encryptionVariant, updated)),\n                expectedVersion: this.machine.metadataVersion\n            });\n\n            if (answer.result === 'success') {\n                this.machine.metadata = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(answer.metadata));\n                this.machine.metadataVersion = answer.version;\n                logger.debug('[API MACHINE] Metadata updated successfully');\n            } else if (answer.result === 'version-mismatch') {\n                if (answer.version > this.machine.metadataVersion) {\n                    this.machine.metadataVersion = answer.version;\n                    this.machine.metadata = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(answer.metadata));\n                }\n                throw new Error('Metadata version mismatch'); // Triggers retry\n            }\n        });\n    }\n\n    /**\n     * Update daemon state (runtime info) - similar to session updateAgentState\n     * Simplified without lock - relies on backoff for retry\n     */\n    async updateDaemonState(handler: (state: DaemonState | null) => DaemonState): Promise<void> {\n        await backoff(async () => {\n            const updated = handler(this.machine.daemonState);\n\n            const answer = await this.socket.emitWithAck('machine-update-state', {\n                machineId: this.machine.id,\n                daemonState: encodeBase64(encrypt(this.machine.encryptionKey, this.machine.encryptionVariant, updated)),\n                expectedVersion: this.machine.daemonStateVersion\n            });\n","sourceCodeStart":376,"sourceCodeEnd":412,"githubUrl":"https://github.com/slopus/happy/blob/b824cd0a4681d41af631a8e422a813873e4455b0/packages/happy-cli/src/api/apiMachine.ts#L376-L412","documentation":"Thrown by updateMachineMetadata when the server responds 'version-mismatch' for machine metadata. Before throwing, the client adopts the server's newer version and metadata (if answer.version is higher) so the next attempt converges; the throw itself is deliberate — it signals the optimistic update conflicted and triggers the caller's retry logic.","triggerScenarios":"Two writers (e.g., this daemon and another instance/machine process) update machine metadata concurrently; the local metadataVersion is stale relative to the server's.","commonSituations":"Running multiple daemons for the same machine; a daemon restarted while a stale keep-alive loop from the previous run was still retrying; rapid successive metadata updates racing.","solutions":["Let the retry logic re-run updateMachineMetadata — the client already adopted the server's newer metadata","Ensure only one daemon instance per machine is running","If mismatches persist, refresh machine state from the server and reapply local edits"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await updateMachineMetadata(metadata);\n} catch (e) {\n  if (e.message === 'Metadata version mismatch') {\n    // client already adopted server version; safe to retry\n    await updateMachineMetadata(metadata);\n  } else throw e;\n}","preventionTips":["Run only one daemon per machine","Serialize metadata writes through a single owner","Treat this error as expected conflict noise, not a crash"],"tags":["version-conflict","optimistic-concurrency","metadata","retry"],"backgroundTag":"version-mismatch","analyzedSha":"b824cd0a4681d41af631a8e422a813873e4455b0","analyzedAt":"2026-08-31T23:12:36.205Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}