{"record":{"id":"9248e6148b12b49b","repo":"can1357/oh-my-pi","slug":"owncloud-share-response-did-not-include-ocs-metada","errorCode":null,"errorMessage":"owncloud share response did not include OCS metadata and data","messagePattern":"owncloud share response did not include OCS metadata and data","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/blob-broker/uploaders-self-hosted.ts","lineNumber":55,"sourceCode":"\tid: string;\n\tname?: string;\n}\n\nfunction nonEmptyString(value: unknown): string | undefined {\n\treturn typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction identifier(value: unknown): string | undefined {\n\treturn typeof value === \"string\" || typeof value === \"number\" ? String(value) : undefined;\n}\n\nfunction ownCloudShare(value: unknown): OwnCloudShare {\n\tif (typeof value !== \"object\" || value === null || !(\"ocs\" in value)) {\n\t\tthrow new Error(\"owncloud share response did not include an OCS envelope\");\n\t}\n\tconst ocs = value.ocs;\n\tif (typeof ocs !== \"object\" || ocs === null || !(\"meta\" in ocs) || !(\"data\" in ocs)) {\n\t\tthrow new Error(\"owncloud share response did not include OCS metadata and data\");\n\t}\n\tconst meta = ocs.meta;\n\tconst data = ocs.data;\n\tif (typeof meta !== \"object\" || meta === null || !(\"statuscode\" in meta)) {\n\t\tthrow new Error(\"owncloud share response did not include an OCS status\");\n\t}\n\tif (typeof data !== \"object\" || data === null || !(\"url\" in data)) {\n\t\tthrow new Error(\"owncloud share response did not include a URL\");\n\t}\n\tconst url = nonEmptyString(data.url);\n\tif (!url) throw new Error(\"owncloud share response did not include a URL\");\n\tconst id = \"id\" in data ? identifier(data.id) : undefined;\n\treturn { statusCode: meta.statuscode, url, ...(id ? { id } : {}) };\n}\n\nfunction plikUpload(value: unknown): PlikUpload {\n\tif (typeof value !== \"object\" || value === null || !(\"id\" in value) || !(\"uploadToken\" in value)) {\n\t\tthrow new Error(\"plik upload metadata did not include an id and upload token\");","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/blob-broker/uploaders-self-hosted.ts#L37-L73","documentation":"This error is thrown by the ownCloudShare response validator when the ownCloud/Nextcloud OCS API response JSON contains an 'ocs' envelope, but that envelope lacks either the 'meta' or 'data' object. The library expects the standard OCS response shape { ocs: { meta: {...}, data: {...} } } when parsing a share-creation reply; anything else is treated as a malformed or unexpected response rather than a valid share.","triggerScenarios":"Calling the ownCloud/Nextcloud share uploader (createOwnCloudUploader -> share -> ownCloudShare) against a server whose HTTP 2xx body is not a well-formed OCS envelope — e.g. the response parsed as JSON but 'ocs' contains only partial fields, or a proxy/gateway returned a JSON body without 'meta'/'data'.","commonSituations":"Pointing the destination at a Nextcloud instance with OCS API version mismatch (e.g. old v1 vs v2 metadata paths), a reverse proxy or CDN intercepting the request and returning its own JSON error page with 200, or an HTML/XML login redirect being coerced through a different parser path.","solutions":["Verify the destination's apiUrl points at the correct OCS endpoint (e.g. https://host/ocs/v1.php or /ocs/v2.php apps path) and the server actually responds with OCS JSON","Check for reverse proxies / SSO redirects rewriting the response; test the share endpoint directly with curl using the same credentials","Confirm server and client OCS API versions match (Nextcloud 'Accept: application/json' vs XML) and upgrade/downgrade accordingly","Log the raw response body at the failure point to see what the server actually returned"],"exampleFix":"// before: response body is a proxy JSON page like {\"error\":\"auth required\"}\nurl = \"https://mycloud.example.com/remote.php/webdav\" // wrong endpoint\n// after: use the OCS share endpoint expected by the uploader\nurl = \"https://mycloud.example.com/ocs/v1.php/apps/files_sharing/api/v1/shares\"","handlingStrategy":"type-guard","validationCode":"function looksLikeOcsResponse(value: unknown): boolean {\n  return (\n    typeof value === \"object\" && value !== null && \"ocs\" in value &&\n    typeof (value as any).ocs === \"object\" && (value as any).ocs !== null &&\n    \"meta\" in (value as any).ocs && \"data\" in (value as any).ocs\n  );\n}","typeGuard":"function isOcsEnvelope(value: unknown): value is { ocs: { meta: object; data: object } } {\n  if (typeof value !== \"object\" || value === null || !(\"ocs\" in value)) return false;\n  const ocs = (value as { ocs?: unknown }).ocs;\n  return typeof ocs === \"object\" && ocs !== null && \"meta\" in ocs && \"data\" in ocs;\n}","tryCatchPattern":"try {\n  const share = await uploader.share();\n} catch (err) {\n  if ((err as Error).message.includes(\"OCS envelope\")) {\n    logger.error(\"ownCloud endpoint did not return OCS JSON — check apiUrl and proxies\", { err });\n  }\n  throw err;\n}","preventionTips":["Test the OCS share endpoint with curl and inspect the JSON before configuring the destination","Ensure reverse proxies don't intercept API routes or return JSON error pages with 200","Pin the OCS API version in the apiUrl and keep client/server versions aligned"],"tags":["owncloud","nextcloud","ocs","response-parsing","network"],"backgroundTag":"api-response-schema-mismatch","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}