{"record":{"id":"22898ef25ed3e777","repo":"trailofbits/algo","slug":"failed-to-write-public-key-file-e","errorCode":null,"errorMessage":"Failed to write public key file: {e}","messagePattern":"Failed to write public key file: (.+?)","errorType":"exception","errorClass":"OSError","httpStatus":null,"severity":"error","filePath":"library/x25519_pubkey.py","lineNumber":116,"sourceCode":"        result[\"public_key\"] = pub_b64\n\n        if module.params[\"public_key_path\"]:\n            pub_path = module.params[\"public_key_path\"]\n            existing = None\n\n            try:\n                with open(pub_path) as f:\n                    existing = f.read().strip()\n            except OSError:\n                existing = None\n\n            if existing != pub_b64:\n                try:\n                    with open(pub_path, \"w\") as f:\n                        f.write(pub_b64)\n                    result[\"changed\"] = True\n                except OSError as e:\n                    module.fail_json(msg=f\"Failed to write public key file: {e}\")\n\n            result[\"public_key_path\"] = pub_path\n\n    except Exception as e:\n        module.fail_json(msg=f\"Failed to derive public key: {e}\")\n\n    module.exit_json(**result)\n\n\ndef main():\n    \"\"\"Entry point when module is executed directly.\"\"\"\n    run_module()\n\n\nif __name__ == \"__main__\":\n    main()\n","sourceCodeStart":98,"sourceCodeEnd":133,"githubUrl":"https://github.com/trailofbits/algo/blob/20e22a8715c198b38c01c1ca62d0953b93587a74/library/x25519_pubkey.py#L98-L133","documentation":"The public key was derived successfully but writing it to pub_path failed with an OSError — typically permission denied on the output directory/file or a nonexistent parent directory.","triggerScenarios":"open(pub_path, 'w') fails because configs/<server>/wireguard/ is root-owned, the parent directory doesn't exist yet, or the filesystem is read-only.","commonSituations":"Running the playbook as a non-root user after a previous sudo run created root-owned configs/, or a prior task that should create the directory was skipped.","solutions":["Fix ownership: sudo chown -R $USER configs/","Ensure the parent directory is created (with mode) before this module runs","Check filesystem is writable and disk not full (df -h)","Re-run the play after fixing permissions"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import os\nd = os.path.dirname(pub_path)\nassert os.path.isdir(d) and os.access(d, os.W_OK), f'cannot write to {d}'","typeGuard":"def writable_dir(p: str) -> bool:\n    import os\n    d = os.path.dirname(p) or '.'\n    return os.path.isdir(d) and os.access(d, os.W_OK)","tryCatchPattern":null,"preventionTips":["Ensure the output directory task runs first with explicit mode","Never run parts of the play as root and other parts as a user"],"tags":["x25519","file-io","permissions","ansible"],"backgroundTag":"file-write-permission-denied","analyzedSha":"20e22a8715c198b38c01c1ca62d0953b93587a74","analyzedAt":"2026-08-28T13:26:02.752Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}