{"record":{"id":"ea32278f6b8e2e46","repo":"appwrite/appwrite","slug":"failed-to-rename-certificate-fullchain-pem-let-s","errorCode":null,"errorMessage":"Failed to rename certificate fullchain.pem. Let's Encrypt log: {stderr} ; {stdout}","messagePattern":"Failed to rename certificate fullchain\\.pem\\. Let's Encrypt log: (.+?) ; (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/Appwrite/Certificates/LetsEncrypt.php","lineNumber":62,"sourceCode":"        // Prepare folder in storage for domain\n        $path = APP_STORAGE_CERTIFICATES . '/' . $domain;\n        if (!\\is_readable($path)) {\n            if (!\\mkdir($path, 0755, true)) {\n                throw new Exception('Failed to create path for certificate.');\n            }\n        }\n\n        // Move generated files\n        if (!@\\rename('/etc/letsencrypt/live/' . $certName . '/cert.pem', APP_STORAGE_CERTIFICATES . '/' . $domain . '/cert.pem')) {\n            throw new Exception('Failed to rename certificate cert.pem. Let\\'s Encrypt log: ' . $stderr . ' ; ' . $stdout);\n        }\n\n        if (!@\\rename('/etc/letsencrypt/live/' . $certName . '/chain.pem', APP_STORAGE_CERTIFICATES . '/' . $domain . '/chain.pem')) {\n            throw new Exception('Failed to rename certificate chain.pem. Let\\'s Encrypt log: ' . $stderr . ' ; ' . $stdout);\n        }\n\n        if (!@\\rename('/etc/letsencrypt/live/' . $certName . '/fullchain.pem', APP_STORAGE_CERTIFICATES . '/' . $domain . '/fullchain.pem')) {\n            throw new Exception('Failed to rename certificate fullchain.pem. Let\\'s Encrypt log: ' . $stderr . ' ; ' . $stdout);\n        }\n\n        if (!@\\rename('/etc/letsencrypt/live/' . $certName . '/privkey.pem', APP_STORAGE_CERTIFICATES . '/' . $domain . '/privkey.pem')) {\n            throw new Exception('Failed to rename certificate privkey.pem. Let\\'s Encrypt log: ' . $stderr . ' ; ' . $stdout);\n        }\n\n        $config = \\implode(PHP_EOL, [\n            \"tls:\",\n            \"  certificates:\",\n            \"    - certFile: /storage/certificates/{$domain}/fullchain.pem\",\n            \"      keyFile: /storage/certificates/{$domain}/privkey.pem\"\n        ]);\n\n        // Save configuration into Traefik using our new cert files\n        if (!\\file_put_contents(APP_STORAGE_CONFIG . '/' . $domain . '.yml', $config)) {\n            throw new Exception('Failed to save Traefik configuration.');\n        }\n","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/appwrite/appwrite/blob/a1d520eea492ebd1da1ef2dc8db5b2b34e277dce/src/Appwrite/Certificates/LetsEncrypt.php#L44-L80","documentation":"PATCH /v1/functions/{functionId}/variables/{variableId} loads the parent function first; an empty getDocument('functions', $functionId) result throws function_not_found (src/Appwrite/Platform/Modules/Functions/Http/Variables/Update.php:89) before any update logic runs.","triggerScenarios":"Updating a variable with a mistyped or stale functionId; patching against a deleted function; wrong project context in the SDK/API key.","commonSituations":"Configuration-rotation scripts holding hardcoded function ids across environment rebuilds; drift between environments where the function id differs.","solutions":["Resolve the function id at runtime (list by name or a stable mapping) before updating variables","Fail fast on the function GET in scripts that rotate many variables","Store (functionId, variableId) pairs together, never separately"],"exampleFix":"// before\nawait functions.variables.update('fnct_stale', varId, undefined, 'rotated');\n\n// after\nconst fn = await functions.get(fnId);\nawait functions.variables.update(fn.$id, varId, undefined, 'rotated');","handlingStrategy":"validation","validationCode":"const fn = (await functions.list()).functions.find((f) => f.$id === fnId);\nif (!fn) throw new Error(`function ${fnId} missing — cannot update its variables`);","typeGuard":null,"tryCatchPattern":"try {\n  await functions.variables.update(fnId, varId, key, value);\n} catch (e) {\n  if (e instanceof AppwriteException && e.code === 'function_not_found') {\n    // re-resolve fnId and retry once, or mark the rotation entry skipped\n  } else throw e;\n}","preventionTips":["Keep (functionId, variableId) pairs together in rotation manifests","Fail fast on a function GET before long rotation batches"],"tags":["appwrite","functions","variables","not-found"],"backgroundTag":"resource-not-found","analyzedSha":"a1d520eea492ebd1da1ef2dc8db5b2b34e277dce","analyzedAt":"2026-08-18T21:34:56.994Z","contentChangedAt":"2026-08-18T21:34:56.994Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}