{"record":{"id":"28f272f9bfa9aa70","repo":"HeyPuter/puter","slug":"internal-error-28f272","errorCode":"internal_error","errorMessage":"Owner not found","messagePattern":"Owner not found","errorType":"http","errorClass":"HttpError","httpStatus":500,"severity":"critical","filePath":"src/backend/controllers/fs/LegacyFSController.ts","lineNumber":1404,"sourceCode":"                signature: query.signature as string,\n            },\n            'write',\n            signingCfg,\n        );\n\n        const uid = typeof query.uid === 'string' ? query.uid : '';\n        const targetEntry = await resolveV1Selector(this.stores.fsEntry, {\n            uid,\n        });\n        if (!targetEntry)\n            throw new HttpError(404, 'Item not found', {\n                legacyCode: 'not_found',\n            });\n\n        // Owner suspension check.\n        const owner = await this.stores.user.getById(targetEntry.userId);\n        if (!owner)\n            throw new HttpError(500, 'Owner not found', {\n                legacyCode: 'internal_error',\n            });\n        if ((owner as { suspended?: unknown }).suspended)\n            throw new HttpError(401, 'Account suspended', {\n                legacyCode: 'account_suspended',\n            });\n\n        const userId = targetEntry.userId;\n        const operation =\n            typeof query.operation === 'string' ? query.operation : 'write';\n\n        // A valid write signature authorises overwriting the file's bytes,\n        // not structural changes. Restrict copy/move/mkdir/rename/delete/trash\n        // to a caller authenticated as the owner — otherwise a recipient of a\n        // write-share could relocate or destroy the source via this endpoint.\n        if (operation !== 'write' && req.actor?.user?.id !== userId) {\n            throw new HttpError(\n                403,","sourceCodeStart":1386,"sourceCodeEnd":1422,"githubUrl":"https://github.com/HeyPuter/puter/blob/908ec23eda38526170322c3edf71ba45ecb1ca95/src/backend/controllers/fs/LegacyFSController.ts#L1386-L1422","documentation":"Thrown by POST /writeFile when the target entry exists but its owning user record could not be loaded from the user store. This is a 500 internal_error — a data-integrity problem: an FS entry references a userId that has no corresponding user row. It is not a client mistake; it indicates a corrupt or partially-migrated database.","triggerScenarios":"POST /writeFile against an entry whose userId points to a deleted/orphaned user row; a migration that created entries without users; foreign-key gap in the store.","commonSituations":"Post-migration orphaned entries; a user hard-deleted while their files remained; test fixtures with synthetic userIds.","solutions":["Report to an operator/maintainer — this is a server-side data integrity bug, not fixable from the client.","As an operator, reconcile the orphaned entry: reassign or purge entries whose userId has no user row.","Re-sign against a different, owned entry as a workaround."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await fetch(writeUrl, { method:'POST', body: form }); }\ncatch (e) {\n  if (e.code === 'internal_error' && /Owner not found/i.test(e.message)) {\n    // not client-fixable; report and pick an alternate target\n  } else throw e;\n}","preventionTips":["This is a server data-integrity defect — surface it to operators immediately.","Do not retry identical requests; it will keep failing.","Add monitoring for orphaned entries (FS rows with no user) to catch this server-side."],"tags":["internal-error","data-integrity","writefile","user-store"],"backgroundTag":null,"analyzedSha":"908ec23eda38526170322c3edf71ba45ecb1ca95","analyzedAt":"2026-08-12T20:53:15.911Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}