Rediger

Debug canvas apps by using Live monitor and Trace

Summary

This article explains how to use Live monitor together with the Trace function to diagnose problems in Microsoft Power Apps canvas apps. This approach helps you troubleshoot problems that occur for only certain users or in specific environments. Live monitor shows real-time events like network calls, data operations, errors, and performance details. The Trace function lets you add custom diagnostic records to capture values from behavior formulas at key moments.

Note

Live monitor isn't a practical option in every scenario, like SharePoint forms, custom portal embeddings, or problems that happen only intermittently. In those cases, see Debug canvas apps without Live monitor for alternative approaches.

Prerequisites

This article builds on Debugging canvas apps with Live monitor and Collaborative troubleshooting using Live monitor. If you're new to Live monitor, review those articles before you proceed.

Combine Live monitor and Trace

Live monitor shows platform-level activity: data operations (getRows, createRow, patch), control evaluations, errors like the HTTP status codes 404 or 429, timing, and delegation indicators.

When you add Trace calls in your behavior formulas (OnSelect, OnVisible, OnStart), you capture context like:

  • The user who's running the app
  • The current environment
  • The active screen
  • Entity counts (rows in collections, related records)
  • Business flags (VIP status, discount eligibility)
  • Elapsed times for operations
  • Any other information that helps you understand app behavior

Together, Live monitor and Trace answer both "what happened" and "why."

View data flowing over the network

Live monitor shows each data operation event by providing:

  • Operation type (getRows, createRow, patch, removeRow)
  • Data source (Dataverse table or connector name)
  • Timing (start, finish, duration)
  • Result (success or error status code)
  • Delegation hints (nondelegable operations trigger client-side processing)

To view the details, select an event. To understand why the operation occurred, correlate the events with nearby Trace records. For example, a surge in getRows calls after a Trace operation that includes the phase: "ApplyFilters" property might indicate an inefficient filter expression.

Tip

If you see HTTP 429 (throttling), review preceding events to check whether a loop or repeated evaluation triggered excessive operations. Optimize formulas or use collections to cache data and reduce network calls.

Use Trace effectively

The Trace function writes a structured record to Live monitor.

Key features:

  • Works only in behavior properties (OnSelect, OnChange, OnVisible, OnStart).
  • Accepts a text message and an optional record payload for extra details.
  • TraceSeverity helps you filter events (Information, Warning, Error). Use Error sparingly.
  • Has minimal performance effect when used appropriately. Remove or guard verbose Trace calls before you run a broad deployment.

Trace data property values by using debug buttons

Because you can't place Trace in data properties like a label's Text property, use temporary debug buttons to capture those values.

To create a debug button:

  1. Add a button that's named btnDebugSnapshot and that has the Visible property set to Param("debug") = "true".

    For more information about how to pass parameters, see Param function.

  2. In OnSelect, call Trace and include a snapshot record.

  3. When you test, add &debug=true to the app URL to show the button.

Tip

Trace the input values that you use to calculate a data property. These values often reveal why the result isn't what you expect.

The following example shows the Visible and OnSelect formulas for a debug snapshot button.

// Visible property: Param("debug") = "true"
// OnSelect:
Trace(
    "Debug: Label value: " & Label1.Text,
    TraceSeverity.Information,
    {
        kind: "DataSnapshot",
        user: User().Email,
        customerCount: CountRows(Customers),
        productCount: CountRows(Products),
        maxPrice: Max(Products, Price),
        selectedProductId: If(!IsBlank(galProducts.Selected), galProducts.Selected.ProductId)
    }
);

Note

Guard debug controls by using query string parameters or role checks so that end users don't see them. Remove these controls before you finalize the app.

Debug checklist

Use this checklist when troubleshooting canvas app problems:

  1. Reproduce the problem with Live monitor open in Studio or in a published session.
  2. Add Trace calls at key phases (start, decision points, end, error handlers).
  3. Use query string parameters (Param) to tag the environment or show debug controls.
  4. Compare traces across users or environments. Look for different flags or counts.
  5. Correlate Trace events with network events (throttling, errors, extra calls).
  6. Remove or guard verbose Trace calls before you run a broad deployment.

Example scenarios

App works for one user but not another

User A submits orders successfully, but User B sees failures and different UI behavior, like a disabled discount checkbox. You suspect the underlying data differs between their accounts.

Goal

Capture what the app sees about each user, including email, roles, customer selection, and discount eligibility. Then, compare it with the data operations in Live monitor.

Steps

  1. Open the app in Power Apps Studio.
  2. Add Trace calls in the OnSelect property of the submit button.
  3. Save and publish the app.
  4. Open Live monitor for the published app.
  5. Select Connect user to invite User A. As User A runs through the app, you see both the built-in events and your custom Trace calls.
  6. Open a new Live monitor instance, and then connect User B in the same way.
  7. Compare the values to find the difference that causes the problem.

Example OnSelect formula together with Trace

// Emit pre-submit context
Trace(
    "Debug: Before Submit",
    TraceSeverity.Information,
    {
        user: User().Email,
        customerId: ddCustomer.Selected.Id,
        cartCount: CountRows(colCart),
        orderCountForCustomer: CountIf(Orders, Customer = ddCustomer.Selected),
        isVIP: ddCustomer.Selected.'VIP Flag',
        env: Param("env"),
        screen: App.ActiveScreen.Name
    }
);

// Perform data operations (simplified)
ForAll(colCart,
    Patch(Orders, Defaults(Orders), {
        Customer: ddCustomer.Selected,
        Product: ThisRecord.Product,
        Quantity: ThisRecord.Quantity
    })
);

// Post-submit trace
Trace(
    "Debug: After Submit",
    TraceSeverity.Information,
    {
        orderCountForCustomer: CountIf(Orders, Customer = ddCustomer.Selected)
    }
);

Analyze the results

In Live monitor, filter by Trace events, button name, or search for "Debug:" in the event data. Compare User A to User B:

  • Do they have different isVIP values? This difference could change discount calculations.
  • Are cart counts identical? If not, the upstream logic differs.
  • Are error traces present only for User B? Expand the event to inspect the error details.

Correlate Trace events with adjacent getRows or patch operations. If User B triggers extra data calls, like a nondelegable filter that forces multiple network requests, you see them in the event table.

App works in one environment but not another

Your app works correctly in Test but fails in Production. For example, a gallery loads no items, and submission is slow. Even though the app is the same, the data in each environment can differ. Missing tables, different column values, larger datasets that trigger delegation limits, or permission differences can cause the app to behave differently.

Goal

Gather environment-specific metadata and counts, and then compare the sequence and status codes of data operations between environments. In this example, the app has one screen that includes a form. This form contains a product that's selected from a gallery and that can be updated. The update works in Test but fails in Production.

Steps

  1. Add an OnVisible Trace on the affected screen:

    Trace(
        "Debug: OnVisible on " & App.ActiveScreen.Name,
        TraceSeverity.Information,
        {
            recordId: varSelectedProduct.Id,
            hasDiscount: varSelectedProduct.HasDiscount,
            relatedOrders: CountIf(Orders, ProductId = varSelectedProduct.Id)
        }
    );
    
  2. Deploy the app with the new traces to production.

  3. Open Live monitor in Test, and then in Production. If necessary, export the logs.

Analyze the results

In the event list:

  • Compare getRows events for Products across environments. Does one return zero results or error codes? A 404 code means the table is missing, 403 means access is denied, and 429 means the requests are throttled.
  • Look for repeated getRows calls. These calls might indicate a nondelegable formula.
  • Compare the Trace values. Do products have different values for relatedOrders or hasDiscount?

If you find a difference, add more Trace calls in which the variable is set, and then examine how the calls are populated.

If you see network errors like 4xx responses, check that tables, flows, and connectors are set up correctly in both environments.