OutSystems Associate Developer common mistakes
OutSystems Associate Developer · Understand the traps and how to avoid them.
Treating a Screen Action and a Server Action as interchangeable, wiring client-side-only logic (like navigating or showing a message) into a Server Action and expecting it to run in the browser.
Both are visually similar in the flow editor and both are 'actions', so candidates assume they execute in the same place; they miss that Server Actions run on the server and cannot directly touch client-side UI elements.
What to do instead
Before building, classify each piece of logic: does it need client context (navigation, client variables, feedback messages, JavaScript) or server context (database access, server-side security)? Put client-dependent steps in the Screen Action and server-dependent steps in a Server Action called from it.
Placing business logic and direct database access in Screen Actions instead of in Server Actions or Service Actions, then being surprised that the logic is not reusable or that security checks can be bypassed.
Screen Actions are the first thing a beginner sees in the flow editor, so everything gets built there; the architectural separation of presentation from logic is not yet internalized.
What to do instead
Adopt the habit of building logic in Server Actions (or Service Actions for cross-module reuse) and having Screen Actions only orchestrate: validate input, call the Server Action, then handle the result and navigation.
Using a Local Variable where a Screen Variable or Input Parameter is required, or vice versa, and then wondering why a value resets on each request or is not available on the screen.
The variable types share similar creation dialogs and the scope differences (per-request vs per-screen-instance vs passed-in) are subtle for newcomers.
What to do instead
Memorize the scope rule: Local Variables live only for the duration of one action execution; Screen Variables persist for the lifetime of the screen instance; Input Parameters are supplied by the caller. Choose based on how long the value must survive and who must supply it.
Building a mobile screen with desktop-style patterns, such as a wide table/grid of records or a screen that assumes a mouse hover, then failing questions about mobile UI behavior.
Candidates transfer web habits directly to mobile without accounting for touch targets, small viewports, and the different set of available UI patterns in mobile modules.
What to do instead
For mobile, default to list-based patterns (list with a card/row item), design for touch (large tap areas, no hover-dependent behavior), and reserve tables for tablet/desktop contexts. When reviewing a mobile screen, ask 'can this be operated with a thumb on a small screen?'
Assuming offline capability is automatic in a mobile app, and not distinguishing what data is available when the device has no connectivity.
Mobile apps look like the web app in the editor, so candidates assume the same always-connected behavior; the offline/local-storage model is a distinct concept that must be learned explicitly.
What to do instead
Study how the mobile app caches data locally and which actions can run offline versus which require the server. For each screen, identify whether it reads from local storage or requires a live server call, and design the sync/refresh step accordingly.
Forgetting to add the required references between modules (or adding references but not publishing/refreshing them), then being unable to use a Server Action or Entity that 'should' be visible.
OutSystems enforces explicit dependency management, but beginners expect everything in the environment to be globally visible, as in a single-project codebase.
What to do instead
Before consuming something from another module, confirm the producer exposes it publicly and that the consumer has a reference to that producer. After changing a producer's public elements, refresh the dependency in the consumer so the new elements appear.
Confusing the roles of the modules in an ODC app (for example, putting UI screens and reusable business logic in the same module, or exposing entities publicly without need), leading to wrong answers about app architecture.
The multi-module structure of an ODC app is new and the boundaries between UI, logic, and library modules are not obvious from the editor alone.
What to do instead
Learn the intended separation: UI/screens live in the app's front-end modules, reusable logic goes in library modules, and entities are exposed only when another module genuinely needs them. When in doubt, ask 'who needs this element?' and place it at the narrowest scope that satisfies that.
Deploying/publishing changes without checking that the app compiles cleanly and without verifying the impact on dependent modules, then misanswering questions about the publish lifecycle.
Candidates treat publish as a save button and skip the validation step; the concept of a 1-Click Publish validating the whole set of changed modules is unfamiliar.
What to do instead
Treat publishing as a build step: read the TrueChange/validation messages, fix errors before publishing, and understand that publishing a producer can require republishing or refreshing consumers. Practice the full edit-validate-publish cycle at least once.
Not handling the empty-result and error cases of an Aggregate or Data Action, building a screen that assumes at least one record exists and then failing questions about runtime behavior.
Beginners test with seeded data that always returns rows, so the zero-row path and the error path are never exercised or considered.
What to do instead
For every query, explicitly decide what the screen shows when the result is empty (empty state / message) and what happens when the action fails (error handling, user feedback). Build both paths once so the pattern becomes automatic.
Skipping input validation and role-based access checks on actions, relying only on hiding UI elements, then getting security-related questions wrong.
Hiding a button feels like security, and validation is easy to defer; candidates do not realize server-side checks are required because the client can be bypassed.
What to do instead
Enforce validation in the action that performs the operation (server-side), and enforce authorization with role checks on the action itself, not just by hiding UI. When reviewing any action, ask 'what stops a malicious caller from invoking this directly?'