Introduction
File storage is a common requirement in enterprise applications. Whether you are archiving generated reports, persisting user-uploaded documents, or integrating with external content management systems. Pega Platform provides a built-in, cloud-compatible mechanism for this through its Repository API, centered on the D_pxNewFile savable data page and the Embed-Repository-File embedded class.
This article walks through a practical, step-by-step implementation of a reusable Activity rule defined on the Embed-Repository-File class, which receives a Base64-encoded file and persists it to any configured Pega repository, whether that is Pega Cloud’s default storage, Amazon S3, Azure Blob Storage, or any other supported provider.
Why an Activity on
Embed-Repository-File?
Placing the logic directly on
Embed-Repository-Filekeeps the rule naturally scoped to file operations, makes it reusable across multiple case types, and leverages the class’s built-in properties (pyContents,pyErrorMessage,pyMessage) without requiring additional mappings.
What Is Embed-Repository-File?
Embed-Repository-File is a platform-level embedded class that acts as a metadata and content container for files stored in any Pega-connected repository. It abstracts away the underlying storage provider. Your application code always interacts with the same structure, regardless of whether the backend is S3, Azure Blob, or a local file system.
Key properties relevant to this implementation:
| Property | Description |
|---|---|
pyContents |
Base64-encoded file content used to populate the file before saving |
pyMessage |
Informational message set on success |
pyErrorMessage |
Error message set when the operation fails or validation fails |
For a full list of available OOTB data pages (D_pxNewFile, D_pxGetFile, D_pxListFiles, etc.), refer to the official Using repository APIs in your application documentation (see References).
Activity Overview: SendFileToRepository
The Activity SendFileToRepository, defined on the Embed-Repository-File class, accepts four input parameters and orchestrates the full upload sequence — including input validation, path construction, file population, persistence, and feedback messaging.
Parameters
| Parameter | Type | Description |
|---|---|---|
DestinyDirectory |
Text | Target directory path in the repository (e.g., reports/2026/) |
FileName |
Text | Name of the file to be created (e.g., monthly_report.pdf) |
FileBase64 |
Text | Base64-encoded content of the file |
RepositoryName |
Text | Name of the configured repository (e.g., pegacloudfilestorage) |
FullPathDestiny |
Text | (Internal — computed in Step 2) Full file path used in the API call |
Flow Summary
The Activity contains 7 steps organized across three logical blocks:
[ Steps 1–5 ] → Main flow (validate → build path → populate → save → success)
[ Step 6 ] → ERROR block (triggered if Save-DataPage fails)
[ Step 7 ] → VALIDATE block (triggered if any input parameter is missing)
Step-by-Step Implementation
Step 1 — Clear Page Messages (Page-Clear-Messages)
The first step resets the step page by clearing any pre-existing messages. This ensures that feedback from any previous execution does not bleed into the current run, an important hygiene step, especially when the Activity is called in a loop or retried.
Method: `Page-Clear-Messages`
Step Page: Default (current `Embed-Repository-File` page)
Step 2 — Validate Inputs and Build Full Path (Property-Set)
This is the most logic-dense step. It has two responsibilities:
2a. Precondition (When Expression — Validation)
Before executing the Property-Set, the Activity evaluates whether any required input parameter is empty. If any of the four parameters (DestinyDirectory, FileName, FileBase64, RepositoryName) is blank, the flow jumps immediately to the VALIDATE block (Step 7), skipping all remaining main-flow steps.
When expression:
Param.DestinyDirectory==""
|| Param.FileName==""
|| Param.FileBase64==""
|| Param.RepositoryName==""
→ Jump To: VALIDATE
2b. Property-Set — Path Construction
If validation passes, the step constructs the full file path by combining DestinyDirectory and FileName. It handles the edge case where the directory string already ends with a / to avoid double-slash paths:
If DestinyDirectory ends with "/" → FullPathDestiny = DestinyDirectory + FileName
Else → FullPathDestiny = DestinyDirectory + "/" + FileName
@if(@endsWith(Param.DestinyDirectory,“/”),Param.DestinyDirectory+Param.FileName,Param.DestinyDirectory+“/”+Param.FileName)
Step 3 — Populate File Content (Property-Set on D_pxNewFile)
This step changes the step page context to D_pxNewFile, loading the data page with the target repository and file path. It then maps the Base64-encoded file content from Param.FileBase64 into the .pyContents property of the data page, effectively staging the file in memory before it is committed.
Method: Property-Set
Step Page: D_pxNewFile[repositoryName: Param.RepositoryName, filePath: Param.FullPathDestiny]
.pyContents = Param.FileBase64
Technical note: The step page must be set correctly here. If D_pxNewFile resolves to a null page (common when parameters are missing or misnamed), the Activity will throw an InvalidReferenceException. Always confirm both repositoryName and filePath are non-empty before this step, which is why Step 2’s validation runs first.
Step 4 — Commit the File to the Repository (Save-DataPage)
This is the step that actually persists the file to the repository. It calls Save-DataPage on D_pxNewFile with the same repositoryName and filePath parameters, instructing the platform to write the staged content to the configured storage backend.
Method: Save-DataPage
Data Page: D_pxNewFile
Parameters passed: repositoryName, filePath (from Param.RepositoryName and Param.FullPathDestiny)
If Save-DataPage throws a PRRuntimeException, the exception is caught, the message is added to the step page, and the flow branches to the ERROR block.
A Transition evaluates the StepStatusFail When condition after the method executes. If the step status is failure, it also branches to the ERROR block.
Step 5 — Success Message (Property-Set-Messages)
Reached only when Step 4 completes successfully. Sets a success message on the .pyMessage property of the step page to confirm the file was uploaded. The Activity then exits immediately via an “Always → Skip remaining steps” transition, ensuring Steps 6 and 7 (error paths) are never executed on a successful run.
Method: Property-Set-Messages
Property: .pyMessage
Message: "File sent successfully."
Step 6 — [ERROR Block] Failure Message (Property-Set-Messages)
Reached when Step 4 fails (either via exception or the StepStatusFail transition). Sets an error message on .pyErrorMessage to notify the calling code that the upload did not succeed.
Block: ERROR
Method: Property-Set-Messages
Property: .pyErrorMessage
Message: "Sorry, there was an error sending your file."
Step 7 — [VALIDATE Block] Missing Parameters Message (Property-Set-Messages)
Reached when Step 2’s precondition detects one or more missing input parameters. Sets a validation message on .pyErrorMessage to inform the caller of the issue.
Block: VALIDATE
Method: Property-Set-Messages
Property: .pyErrorMessage
Message: "All parameters are required for this activity."
Technical Considerations
Pega Cloud compatibility: D_pxNewFile and Save-DataPage are the recommended, cloud-compliant replacement for the deprecated Connect-File approach. The default repository name on Pega Cloud is pegacloudfilestorage.
File size limit: By default, D_pxNewFile supports in-memory file content up to 45 MB. For larger files, increase the Dynamic System Setting repository/maxFileSizeInMemory or consider streaming via pyStream instead of pyContents.
Base64 encoding: The caller is responsible for encoding the file content as Base64 before passing it to Param.FileBase64. This is standard when sourcing files from REST payloads or attachment properties.
Repository access roles: Ensure the executing operator has either the PegaRULES:RepositoryAdministrator or PegaRULES:RepositoryUser role assigned. Operations will fail silently or with a permission error otherwise.
Reusability: Because the Activity is defined on Embed-Repository-File (not on a specific application class), it can be called from any class in your application via a Call method, keeping your implementation DRY and consistent.
Conclusion
This Activity provides a clean, reusable, and cloud-safe pattern for programmatically uploading files to any Pega-configured repository. By combining input validation, smart path construction, and structured error routing, all within a single Activity on Embed-Repository-File, you get a robust utility that integrates naturally into any case or data flow.
Whether you are archiving case attachments, persisting generated documents, or bridging with external storage backends, this pattern gives you a solid foundation to build on.
References
-
Using repository APIs in your application – Pega Documentation
-
Use case: Process inbound file attachments for storage in a repository – Pega Documentation
-
File Access – Pega Documentation
-
Integrating with file and content management systems – Pega Documentation
-
Troubleshooting BIX in Pega Cloud environments – Pega Documentation
-
Creating a repository – Pega Documentation








